blob: ab43451f22fe0d5b96e59f24c2cf4be8df09cec9 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- Update the byte permission maps following a system call. ---*/
4/*--- vg_syscall_mem.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file LICENSE.
30*/
31
32#include "vg_include.h"
33
34/* vg_unsafe.h should NOT be included into any file except this
35 one. */
36#include "vg_unsafe.h"
37
38
39/* All system calls are channelled through vg_wrap_syscall. It does
40 three things:
41
42 * optionally, checks the permissions for the args to the call
43
44 * perform the syscall, usually by passing it along to the kernel
45 unmodified. However, because we simulate signals ourselves,
46 signal-related syscalls are routed to vg_signal.c, and are not
47 delivered to the kernel.
48
49 * Update the permission maps following the syscall.
50
51 A magical piece of assembly code, vg_do_syscall(), in vg_syscall.S
52 does the tricky bit of passing a syscall to the kernel, whilst
53 having the simulator retain control.
54*/
55
56static void make_noaccess ( Addr a, UInt len )
57{
58 if (VG_(clo_instrument))
59 VGM_(make_noaccess) ( a, len );
60}
61
62static void make_writable ( Addr a, UInt len )
63{
64 if (VG_(clo_instrument))
65 VGM_(make_writable) ( a, len );
66}
67
68static void make_readable ( Addr a, UInt len )
69{
70 if (VG_(clo_instrument))
71 VGM_(make_readable) ( a, len );
72}
73
74static void make_readwritable ( Addr a, UInt len )
75{
76 if (VG_(clo_instrument))
77 VGM_(make_readwritable) ( a, len );
78}
79
80static
sewardj8c824512002-04-14 04:16:48 +000081void must_be_writable ( ThreadState* tst,
82 Char* syscall_name, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +000083{
84 Bool ok;
85 Addr bad_addr;
86 /* VG_(message)(Vg_DebugMsg,"must be writable: %x .. %x",
87 base,base+size-1); */
88 if (!VG_(clo_instrument))
89 return;
90 ok = VGM_(check_writable) ( base, size, &bad_addr );
91 if (!ok)
sewardj8c824512002-04-14 04:16:48 +000092 VG_(record_param_err) ( tst, bad_addr, True, syscall_name );
sewardjde4a1d02002-03-22 01:27:54 +000093}
94
95static
sewardj8c824512002-04-14 04:16:48 +000096void must_be_readable ( ThreadState* tst,
97 Char* syscall_name, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +000098{
99 Bool ok;
100 Addr bad_addr;
101 /* VG_(message)(Vg_DebugMsg,"must be readable: %x .. %x",
102 base,base+size-1); */
103 if (!VG_(clo_instrument))
104 return;
105 ok = VGM_(check_readable) ( base, size, &bad_addr );
106 if (!ok)
sewardj8c824512002-04-14 04:16:48 +0000107 VG_(record_param_err) ( tst, bad_addr, False, syscall_name );
sewardjde4a1d02002-03-22 01:27:54 +0000108}
109
110static
sewardj8c824512002-04-14 04:16:48 +0000111void must_be_readable_asciiz ( ThreadState* tst,
112 Char* syscall_name, UInt str )
sewardjde4a1d02002-03-22 01:27:54 +0000113{
114 Bool ok = True;
115 Addr bad_addr;
116 /* VG_(message)(Vg_DebugMsg,"must be readable asciiz: 0x%x",str); */
117 if (!VG_(clo_instrument))
118 return;
119 ok = VGM_(check_readable_asciiz) ( (Addr)str, &bad_addr );
120 if (!ok)
sewardj8c824512002-04-14 04:16:48 +0000121 VG_(record_param_err) ( tst, bad_addr, False, syscall_name );
sewardjde4a1d02002-03-22 01:27:54 +0000122}
123
124
125/* Set memory permissions, based on PROT_* values for mmap/mprotect,
126 into the permissions our scheme understands. Dunno if this is
127 really correct. */
128
129static void approximate_mmap_permissions ( Addr a, UInt len, UInt prot )
130{
131 /* PROT_READ and PROT_WRITE --> readable
132 PROT_READ only --> readable
133 PROT_WRITE only --> writable
134 NEITHER --> noaccess
135 */
136 if (prot & PROT_READ)
137 make_readable(a,len);
138 else
139 if (prot & PROT_WRITE)
140 make_writable(a,len);
141 else
142 make_noaccess(a,len);
143}
144
145
146/* Dereference a pointer, but only after checking that it's
147 safe to do so. If not, return the default.
148*/
149static
150UInt safe_dereference ( Addr aa, UInt defawlt )
151{
152 if (!VG_(clo_instrument))
153 return * (UInt*)aa;
154 if (VGM_(check_readable)(aa,4,NULL))
155 return * (UInt*)aa;
156 else
157 return defawlt;
158}
159
160
161/* Is this a Linux kernel error return value? */
162/* From:
163 http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
164 linux/i386/sysdep.h?
165 rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
166
167 QUOTE:
168
169 Linux uses a negative return value to indicate syscall errors,
170 unlike most Unices, which use the condition codes' carry flag.
171
172 Since version 2.1 the return value of a system call might be
173 negative even if the call succeeded. E.g., the `lseek' system call
174 might return a large offset. Therefore we must not anymore test
175 for < 0, but test for a real error by making sure the value in %eax
176 is a real error number. Linus said he will make sure the no syscall
177 returns a value in -1 .. -4095 as a valid result so we can savely
178 test with -4095.
179
180 END QUOTE
181*/
182Bool VG_(is_kerror) ( Int res )
183{
184 if (res >= -4095 && res <= -1)
185 return True;
186 else
187 return False;
188}
189
190static
191UInt get_shm_size ( Int shmid )
192{
193 struct shmid_ds buf;
194 long __res;
195 __asm__ volatile ( "int $0x80"
196 : "=a" (__res)
197 : "0" (__NR_ipc),
198 "b" ((long)(24) /*IPCOP_shmctl*/),
199 "c" ((long)(shmid)),
200 "d" ((long)(IPC_STAT)),
201 "S" ((long)(0)),
202 "D" ((long)(&buf)) );
203 if ( VG_(is_kerror) ( __res ) )
204 return 0;
205
206 return buf.shm_segsz;
207}
208
209static
sewardj8c824512002-04-14 04:16:48 +0000210Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000211{
212 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
213 Char *result = VG_(malloc) ( aid, len );
214 VG_(strcpy) ( result, s1 );
215 VG_(strcat) ( result, s2 );
216 return result;
217}
218
219static
sewardj8c824512002-04-14 04:16:48 +0000220void must_be_readable_sendmsg ( ThreadState* tst,
221 Char *msg, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +0000222{
223 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_TRANSIENT );
sewardj8c824512002-04-14 04:16:48 +0000224 must_be_readable ( tst, outmsg, base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000225 VG_(free) ( VG_AR_TRANSIENT, outmsg );
226}
227
228static
sewardj8c824512002-04-14 04:16:48 +0000229void must_be_writable_recvmsg ( ThreadState* tst,
230 Char *msg, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +0000231{
232 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_TRANSIENT );
sewardj8c824512002-04-14 04:16:48 +0000233 must_be_writable ( tst, outmsg, base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000234 VG_(free) ( VG_AR_TRANSIENT, outmsg );
235}
236
237static
sewardj8c824512002-04-14 04:16:48 +0000238void make_readable_recvmsg ( ThreadState* tst,
239 Char *fieldName, UInt base, UInt size )
sewardjde4a1d02002-03-22 01:27:54 +0000240{
241 make_readable( base, size );
242}
243
244static
sewardj8c824512002-04-14 04:16:48 +0000245void msghdr_foreachfield (
246 ThreadState* tst,
247 struct msghdr *msg,
248 void (*foreach_func)( ThreadState*, Char *, UInt, UInt )
249 )
sewardjde4a1d02002-03-22 01:27:54 +0000250{
251 if ( !msg )
252 return;
253
sewardj8c824512002-04-14 04:16:48 +0000254 foreach_func ( tst, "(msg)", (Addr)msg, sizeof( struct msghdr ) );
sewardjde4a1d02002-03-22 01:27:54 +0000255
256 if ( msg->msg_name )
sewardj8c824512002-04-14 04:16:48 +0000257 foreach_func ( tst,
258 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000259 (Addr)msg->msg_name, msg->msg_namelen );
260
261 if ( msg->msg_iov ) {
262 struct iovec *iov = msg->msg_iov;
263 UInt i;
264
sewardj8c824512002-04-14 04:16:48 +0000265 foreach_func ( tst,
266 "(msg.msg_iov)",
sewardjde4a1d02002-03-22 01:27:54 +0000267 (Addr)iov, msg->msg_iovlen * sizeof( struct iovec ) );
268
269 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
sewardj8c824512002-04-14 04:16:48 +0000270 foreach_func ( tst,
271 "(msg.msg_iov[i]",
sewardjde4a1d02002-03-22 01:27:54 +0000272 (Addr)iov->iov_base, iov->iov_len );
273 }
274
275 if ( msg->msg_control )
sewardj8c824512002-04-14 04:16:48 +0000276 foreach_func ( tst,
277 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000278 (Addr)msg->msg_control, msg->msg_controllen );
279}
280
281
282/* Records the current end of the data segment so we can make sense of
283 calls to brk(). Initial value set by hdm_init_memory_audit(). */
284Addr VGM_(curr_dataseg_end);
285
286
sewardj2e93c502002-04-12 11:12:52 +0000287
sewardjde4a1d02002-03-22 01:27:54 +0000288/* The Main Entertainment ... */
289
sewardj2e93c502002-04-12 11:12:52 +0000290void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +0000291{
sewardj2e93c502002-04-12 11:12:52 +0000292 Bool sane_before_call = True;
293 Bool sane_after_call = True;
294 ThreadState* tst = VG_(get_thread_state)( tid );
295 UInt syscallno = tst->m_eax;
296 UInt arg1 = tst->m_ebx;
297 UInt arg2 = tst->m_ecx;
298 UInt arg3 = tst->m_edx;
299 UInt arg4 = tst->m_esi;
300 UInt arg5 = tst->m_edi;
sewardjde4a1d02002-03-22 01:27:54 +0000301
302 /* Do not make this unsigned! */
303 Int res;
304
sewardjde4a1d02002-03-22 01:27:54 +0000305 VGP_PUSHCC(VgpSyscall);
306
307 /* Since buggy syscall wrappers sometimes break this, we may as well
308 check ourselves. */
309 if (! VG_(first_and_last_secondaries_look_plausible))
310 sane_before_call = False;
311
312 /* the syscall no is in %eax. For syscalls with <= 5 args,
313 args 1 .. 5 to the syscall are in %ebx %ecx %edx %esi %edi.
314 For calls with > 5 args, %ebx points to a lump of memory
315 containing the args.
316
317 The result is returned in %eax. If this value >= 0, the call
318 succeeded, and this is the return value. If < 0, it failed, and
319 the negation of this value is errno. To be more specific,
320 if res is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
321 (kernel 2.4.9 sources, include/asm-i386/errno.h)
322 then it indicates an error. Otherwise it doesn't.
323
324 Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
325 (inclusive?) indicate error returns. Not sure where the -4095
326 comes from.
327 */
328
329 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +0000330 VG_(printf)("SYSCALL[%d,%d](%3d): ",
331 VG_(getpid)(), tid, syscallno);
sewardjde4a1d02002-03-22 01:27:54 +0000332
333 switch (syscallno) {
334
sewardj7e87e382002-05-03 19:09:05 +0000335 case __NR_exit:
336 VG_(panic)("syscall exit() not caught by the scheduler?!");
337 break;
338
sewardjde4a1d02002-03-22 01:27:54 +0000339 case __NR_sigaltstack:
340 VG_(unimplemented)
341 ("client signals on alternative stack (SA_ONSTACK)");
342 break;
343
344 case __NR_clone:
345 VG_(unimplemented)
sewardj827d95b2002-04-16 02:09:31 +0000346 ("clone(): not supported by Valgrind.\n "
347 "We do now support programs linked against\n "
348 "libpthread.so, though. Re-run with -v and ensure that\n "
349 "you are picking up Valgrind's implementation of libpthread.so.");
sewardjde4a1d02002-03-22 01:27:54 +0000350 break;
351
352# if defined(__NR_modify_ldt)
353 case __NR_modify_ldt:
354 VG_(unimplemented)
sewardj7e87e382002-05-03 19:09:05 +0000355 ("modify_ldt(): I (JRS) haven't investigated this yet; sorry.\n "
356 "This might be caused by linking to NVidia's libGL.so, so\n "
357 "avoiding it, if you can, _might_ help you. For example,\n "
358 "re-build any Qt libraries you are using without OpenGL support.");
sewardjde4a1d02002-03-22 01:27:54 +0000359 break;
360# endif
361
sewardj73f1f072002-03-29 14:22:46 +0000362 /* !!!!!!!!!! New, untested syscalls !!!!!!!!!!!!!!!!!!!!! */
363
sewardj6e435c02002-04-24 02:24:44 +0000364# if defined(__NR_madvise)
365 case __NR_madvise: /* syscall 219 */
366 /* int madvise(void *start, size_t length, int advice ); */
367 if (VG_(clo_trace_syscalls))
368 VG_(printf)("madvise ( %p, %d, %d )\n", arg1,arg2,arg3);
369 KERNEL_DO_SYSCALL(tid,res);
370 break;
371# endif
372
sewardj6af4b5d2002-04-16 04:40:49 +0000373# if defined(__NR_mremap)
374 /* Is this really right? Perhaps it should copy the permissions
375 from the old area into the new. Unclear from the Linux man
376 pages what this really does. Also, the flags don't look like
377 they mean the same as the standard mmap flags, so that's
378 probably wrong too. */
379 case __NR_mremap: /* syscall 163 */
380 /* void* mremap(void * old_address, size_t old_size,
381 size_t new_size, unsigned long flags); */
382 if (VG_(clo_trace_syscalls))
383 VG_(printf)("mremap ( %p, %d, %d, 0x%x )\n",
384 arg1, arg2, arg3, arg4);
385 must_be_writable ( tst, "mremap(old_address)", arg1, arg2 );
386 KERNEL_DO_SYSCALL(tid,res);
387 if (!VG_(is_kerror)(res)) {
388 /* Copied from munmap() wrapper. */
389 Addr start = arg1;
390 Addr length = arg2;
391 while ((start % VKI_BYTES_PER_PAGE) > 0) { start--; length++; }
392 while (((start+length) % VKI_BYTES_PER_PAGE) > 0) { length++; }
393 make_noaccess( start, length );
394 VG_(symtab_notify_munmap) ( start, length );
395 approximate_mmap_permissions( (Addr)res, arg3, arg4 );
396 }
397 break;
398# endif
399
sewardj73f1f072002-03-29 14:22:46 +0000400 case __NR_nice: /* syscall 34 */
401 /* int nice(int inc); */
402 if (VG_(clo_trace_syscalls))
403 VG_(printf)("nice ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000404 KERNEL_DO_SYSCALL(tid,res);
sewardj73f1f072002-03-29 14:22:46 +0000405 break;
406
sewardjde4a1d02002-03-22 01:27:54 +0000407 /* !!!!!!!!!! New, untested syscalls, 14 Mar 02 !!!!!!!!!! */
408
sewardjd7f07662002-03-24 10:49:46 +0000409# if defined(__NR_setresgid32)
410 case __NR_setresgid32: /* syscall 210 */
411 /* int setresgid(gid_t rgid, gid_t egid, gid_t sgid); */
412 if (VG_(clo_trace_syscalls))
413 VG_(printf)("setresgid32 ( %d, %d, %d )\n", arg1, arg2, arg3);
sewardj2e93c502002-04-12 11:12:52 +0000414 KERNEL_DO_SYSCALL(tid,res);
sewardjd7f07662002-03-24 10:49:46 +0000415 break;
416# endif
417
sewardjde4a1d02002-03-22 01:27:54 +0000418# if defined(__NR_setfsuid32)
419 case __NR_setfsuid32: /* syscall 215 */
420 /* int setfsuid(uid_t fsuid); */
421 if (VG_(clo_trace_syscalls))
422 VG_(printf)("setfsuid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000423 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000424 break;
425# endif
426
427# if defined(__NR__sysctl)
428 case __NR__sysctl:
429 /* int _sysctl(struct __sysctl_args *args); */
430 if (VG_(clo_trace_syscalls))
431 VG_(printf)("_sysctl ( %p )\n", arg1 );
sewardj8c824512002-04-14 04:16:48 +0000432 must_be_writable ( tst, "_sysctl(args)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +0000433 sizeof(struct __sysctl_args) );
sewardj2e93c502002-04-12 11:12:52 +0000434 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000435 if (!VG_(is_kerror)(res))
436 make_readable ( arg1, sizeof(struct __sysctl_args) );
437 break;
438# endif
439
440# if defined(__NR_sched_getscheduler)
441 case __NR_sched_getscheduler:
442 /* int sched_getscheduler(pid_t pid); */
443 if (VG_(clo_trace_syscalls))
444 VG_(printf)("sched_getscheduler ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000445 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000446 break;
447# endif
448
449# if defined(__NR_sched_setscheduler)
450 case __NR_sched_setscheduler:
451 /* int sched_setscheduler(pid_t pid, int policy,
452 const struct sched_param *p); */
453 if (VG_(clo_trace_syscalls))
454 VG_(printf)("sched_setscheduler ( %d, %d, %p )\n",arg1,arg2,arg3);
455 if (arg3 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +0000456 must_be_readable( tst,
457 "sched_setscheduler(struct sched_param *p)",
sewardjde4a1d02002-03-22 01:27:54 +0000458 arg3, sizeof(struct sched_param));
sewardj2e93c502002-04-12 11:12:52 +0000459 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000460 break;
461# endif
462
463# if defined(__NR_mlockall)
464 case __NR_mlockall:
465 /* int mlockall(int flags); */
466 if (VG_(clo_trace_syscalls))
467 VG_(printf)("mlockall ( %x )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000468 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000469 break;
470# endif
471
472# if defined(__NR_munlockall)
473 case __NR_munlockall:
474 /* int munlockall(void); */
475 if (VG_(clo_trace_syscalls))
476 VG_(printf)("munlockall ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000477 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000478 break;
479# endif
480
481#if defined(__NR_sched_get_priority_max)
482 case __NR_sched_get_priority_max:
483 /* int sched_get_priority_max(int policy); */
484 if (VG_(clo_trace_syscalls))
485 VG_(printf)("sched_get_priority_max ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000486 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000487 break;
488# endif
489
sewardj9dfb4a72002-04-27 01:56:30 +0000490#if defined(__NR_sched_get_priority_min)
491 case __NR_sched_get_priority_min: /* syscall 160 */
492 /* int sched_get_priority_min(int policy); */
493 if (VG_(clo_trace_syscalls))
494 VG_(printf)("sched_get_priority_min ( %d )\n", arg1);
495 KERNEL_DO_SYSCALL(tid,res);
496 break;
497# endif
498
499#if defined(__NR_setpriority)
500 case __NR_setpriority: /* syscall 97 */
501 /* int setpriority(int which, int who, int prio); */
502 if (VG_(clo_trace_syscalls))
503 VG_(printf)("setpriority ( %d, %d, %d )\n", arg1, arg2, arg3);
504 KERNEL_DO_SYSCALL(tid,res);
505 break;
506# endif
507
sewardjde5ac182002-04-27 02:13:24 +0000508#if defined(__NR_getpriority)
509 case __NR_getpriority: /* syscall 96 */
510 /* int getpriority(int which, int who); */
511 if (VG_(clo_trace_syscalls))
512 VG_(printf)("getpriority ( %d, %d )\n", arg1, arg2);
513 KERNEL_DO_SYSCALL(tid,res);
514 break;
515# endif
516
sewardjde4a1d02002-03-22 01:27:54 +0000517# if defined(__NR_setfsgid)
518 case __NR_setfsgid: /* syscall 139 */
519 /* int setfsgid(gid_t gid); */
520 if (VG_(clo_trace_syscalls))
521 VG_(printf)("setfsgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000522 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000523 break;
524# endif
525
526# if defined(__NR_setregid)
527 case __NR_setregid: /* syscall 71 */
528 /* int setregid(gid_t rgid, gid_t egid); */
529 if (VG_(clo_trace_syscalls))
530 VG_(printf)("setregid ( %d, %d )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +0000531 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000532 break;
533# endif
534
535# if defined(__NR_setresuid)
536 case __NR_setresuid: /* syscall 164 */
537 /* int setresuid(uid_t ruid, uid_t euid, uid_t suid); */
538 if (VG_(clo_trace_syscalls))
539 VG_(printf)("setresuid ( %d, %d, %d )\n", arg1, arg2, arg3);
sewardj2e93c502002-04-12 11:12:52 +0000540 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000541 break;
542# endif
543
544# if defined(__NR_setfsuid)
545 case __NR_setfsuid: /* syscall 138 */
546 /* int setfsuid(uid_t uid); */
547 if (VG_(clo_trace_syscalls))
548 VG_(printf)("setfsuid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000549 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000550 break;
551# endif
552
553 /* !!!!!!!!!! New, untested syscalls, 8 Mar 02 !!!!!!!!!!! */
554
555# if defined(__NR_sendfile)
556 case __NR_sendfile: /* syscall 187 */
557 /* ssize_t sendfile(int out_fd, int in_fd, off_t *offset,
558 size_t count) */
559 if (VG_(clo_trace_syscalls))
560 VG_(printf)("sendfile ( %d, %d, %p, %d )\n",arg1,arg2,arg3,arg4);
sewardj8c824512002-04-14 04:16:48 +0000561 must_be_writable( tst, "sendfile(offset)", arg3, sizeof(off_t) );
sewardj2e93c502002-04-12 11:12:52 +0000562 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000563 if (!VG_(is_kerror)(res)) {
564 make_readable( arg3, sizeof( off_t ) );
565 }
566 break;
567# endif
568
569 /* !!!!!!!!!! New, untested syscalls, 7 Mar 02 !!!!!!!!!!! */
570
571# if defined(__NR_pwrite)
572 case __NR_pwrite: /* syscall 181 */
573 /* ssize_t pwrite (int fd, const void *buf, size_t nbytes,
574 off_t offset); */
575 if (VG_(clo_trace_syscalls))
576 VG_(printf)("pwrite ( %d, %p, %d, %d )\n", arg1, arg2, arg3, arg4);
sewardj8c824512002-04-14 04:16:48 +0000577 must_be_readable( tst, "pwrite(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000578 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000579 break;
580# endif
581
582 /* !!!!!!!!!! New, untested syscalls, 6 Mar 02 !!!!!!!!!!! */
583
584 case __NR_sync: /* syscall 36 */
585 /* int sync(); */
586 if (VG_(clo_trace_syscalls))
587 VG_(printf)("sync ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000588 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000589 break;
590
591 case __NR_fstatfs: /* syscall 100 */
592 /* int fstatfs(int fd, struct statfs *buf); */
593 if (VG_(clo_trace_syscalls))
594 VG_(printf)("fstatfs ( %d, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000595 must_be_writable( tst, "stat(buf)", arg2, sizeof(struct statfs) );
sewardj2e93c502002-04-12 11:12:52 +0000596 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000597 if (!VG_(is_kerror)(res))
598 make_readable( arg2, sizeof(struct statfs) );
599 break;
600
601 /* !!!!!!!!!! New, untested syscalls, 4 Mar 02 !!!!!!!!!!! */
602
603 case __NR_pause: /* syscall 29 */
604 /* int pause(void); */
605 if (VG_(clo_trace_syscalls))
606 VG_(printf)("pause ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000607 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000608 break;
609
610 case __NR_getsid: /* syscall 147 */
611 /* pid_t getsid(pid_t pid); */
612 if (VG_(clo_trace_syscalls))
613 VG_(printf)("getsid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000614 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000615 break;
616
617# if defined(__NR_pread)
618 case __NR_pread: /* syscall 180 */
619 /* ssize_t pread(int fd, void *buf, size_t count, off_t offset); */
620 if (VG_(clo_trace_syscalls))
621 VG_(printf)("pread ( %d, %p, %d, %d ) ...\n",arg1,arg2,arg3,arg4);
sewardj8c824512002-04-14 04:16:48 +0000622 must_be_writable( tst, "pread(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000623 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000624 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +0000625 VG_(printf)("SYSCALL[%d] pread ( %d, %p, %d, %d ) --> %d\n",
626 VG_(getpid)(),
sewardjde4a1d02002-03-22 01:27:54 +0000627 arg1, arg2, arg3, arg4, res);
628 if (!VG_(is_kerror)(res) && res > 0) {
629 make_readable( arg2, res );
630 }
631 break;
632# endif
633
634 /* !!!!!!!!!! New, untested syscalls, 27 Feb 02 !!!!!!!!!! */
635
636 case __NR_mknod: /* syscall 14 */
637 /* int mknod(const char *pathname, mode_t mode, dev_t dev); */
638 if (VG_(clo_trace_syscalls))
639 VG_(printf)("mknod ( %p, 0x%x, 0x%x )\n", arg1, arg2, arg3 );
sewardj8c824512002-04-14 04:16:48 +0000640 must_be_readable_asciiz( tst, "mknod(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000641 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000642 break;
643
644 case __NR_flock: /* syscall 143 */
645 /* int flock(int fd, int operation); */
646 if (VG_(clo_trace_syscalls))
647 VG_(printf)("flock ( %d, %d )\n", arg1, arg2 );
sewardj2e93c502002-04-12 11:12:52 +0000648 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000649 break;
650
651# if defined(__NR_rt_sigsuspend)
652 /* Viewed with great suspicion by me, but, hey, let's do it
653 anyway ... */
654 case __NR_rt_sigsuspend: /* syscall 179 */
655 /* int sigsuspend(const sigset_t *mask); */
656 if (VG_(clo_trace_syscalls))
657 VG_(printf)("sigsuspend ( %p )\n", arg1 );
658 if (arg1 != (Addr)NULL) {
659 /* above NULL test is paranoia */
sewardj8c824512002-04-14 04:16:48 +0000660 must_be_readable( tst, "sigsuspend(mask)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +0000661 sizeof(vki_ksigset_t) );
662 }
sewardj2e93c502002-04-12 11:12:52 +0000663 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000664 break;
665# endif
666
667 case __NR_init_module: /* syscall 128 */
668 /* int init_module(const char *name, struct module *image); */
669 if (VG_(clo_trace_syscalls))
670 VG_(printf)("init_module ( %p, %p )\n", arg1, arg2 );
sewardj8c824512002-04-14 04:16:48 +0000671 must_be_readable_asciiz( tst, "init_module(name)", arg1 );
672 must_be_readable( tst, "init_module(image)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +0000673 sizeof(struct module) );
sewardj2e93c502002-04-12 11:12:52 +0000674 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000675 break;
676
677 case __NR_ioperm: /* syscall 101 */
678 /* int ioperm(unsigned long from, unsigned long num, int turn_on); */
679 if (VG_(clo_trace_syscalls))
680 VG_(printf)("ioperm ( %d, %d, %d )\n", arg1, arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000681 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000682 break;
683
684 case __NR_capget: /* syscall 184 */
685 /* int capget(cap_user_header_t header, cap_user_data_t data); */
686 if (VG_(clo_trace_syscalls))
687 VG_(printf)("capget ( %p, %p )\n", arg1, arg2 );
sewardj8c824512002-04-14 04:16:48 +0000688 must_be_readable( tst, "capget(header)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +0000689 sizeof(vki_cap_user_header_t) );
sewardj8c824512002-04-14 04:16:48 +0000690 must_be_writable( tst, "capget(data)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +0000691 sizeof( vki_cap_user_data_t) );
sewardj2e93c502002-04-12 11:12:52 +0000692 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000693 if (!VG_(is_kerror)(res) && arg2 != (Addr)NULL)
694 make_readable ( arg2, sizeof( vki_cap_user_data_t) );
695 break;
696
697 /* !!!!!!!!!!!!!!!!!!!!! mutant ones !!!!!!!!!!!!!!!!!!!!! */
698
699 case __NR_execve:
700 /* int execve (const char *filename,
701 char *const argv [],
702 char *const envp[]); */
703 if (VG_(clo_trace_syscalls))
704 VG_(printf)("execve ( %p(%s), %p, %p ) --- NOT CHECKED\n",
705 arg1, arg1, arg2, arg3);
706 /* Make any binding for LD_PRELOAD disappear, so that child
707 processes don't get traced into. */
708 if (!VG_(clo_trace_children)) {
709 Int i;
710 Char** envp = (Char**)arg3;
711 for (i = 0; envp[i] != NULL; i++) {
712 if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0) {
713 VG_(mash_LD_PRELOAD_string)(&envp[i][11]);
714 }
715 }
716 }
sewardj2e93c502002-04-12 11:12:52 +0000717 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000718 /* Should we still be alive here? Don't think so. */
719 /* Actually, above comment is wrong. execve can fail, just
720 like any other syscall -- typically the file to exec does
721 not exist. Hence: */
722 vg_assert(VG_(is_kerror)(res));
723 break;
724
sewardjde4a1d02002-03-22 01:27:54 +0000725 /* !!!!!!!!!!!!!!!!!!!!! end !!!!!!!!!!!!!!!!!!!!! */
726
727 case __NR_access: /* syscall 33 */
728 /* int access(const char *pathname, int mode); */
729 if (VG_(clo_trace_syscalls))
730 VG_(printf)("access ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000731 must_be_readable_asciiz( tst, "access(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000732 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000733 break;
734
735 case __NR_alarm: /* syscall 27 */
736 /* unsigned int alarm(unsigned int seconds); */
737 if (VG_(clo_trace_syscalls))
738 VG_(printf)("alarm ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000739 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000740 break;
741
742 case __NR_brk: /* syscall 45 */
743 /* Haven't a clue if this is really right. */
744 /* int brk(void *end_data_segment); */
745 if (VG_(clo_trace_syscalls))
746 VG_(printf)("brk ( %p ) --> ",arg1);
sewardj2e93c502002-04-12 11:12:52 +0000747 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000748 if (VG_(clo_trace_syscalls))
749 VG_(printf)("0x%x\n", res);
750
751 if (!VG_(is_kerror)(res)) {
752 if (arg1 == 0) {
753 /* Just asking where the current end is. (???) */
754 VGM_(curr_dataseg_end) = res;
755 } else
756 if (arg1 < VGM_(curr_dataseg_end)) {
757 /* shrinking the data segment. */
758 make_noaccess( (Addr)arg1,
759 VGM_(curr_dataseg_end)-arg1 );
760 VGM_(curr_dataseg_end) = arg1;
761 } else
762 if (arg1 > VGM_(curr_dataseg_end) && res != 0) {
763 /* asked for more memory, and got it */
764 /*
765 VG_(printf)("BRK: new area %x .. %x\n",
766 VGM_(curr_dataseg_end, arg1-1 );
767 */
768 make_writable ( (Addr)VGM_(curr_dataseg_end),
769 arg1-VGM_(curr_dataseg_end) );
770 VGM_(curr_dataseg_end) = arg1;
771 }
772 }
773 break;
774
775 case __NR_chdir: /* syscall 12 */
776 /* int chdir(const char *path); */
777 if (VG_(clo_trace_syscalls))
778 VG_(printf)("chdir ( %p )\n", arg1);
sewardj8c824512002-04-14 04:16:48 +0000779 must_be_readable_asciiz( tst, "chdir(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000780 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000781 break;
782
783 case __NR_chmod: /* syscall 15 */
784 /* int chmod(const char *path, mode_t mode); */
785 if (VG_(clo_trace_syscalls))
786 VG_(printf)("chmod ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000787 must_be_readable_asciiz( tst, "chmod(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000788 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000789 break;
790
791# if defined(__NR_chown32)
792 case __NR_chown32: /* syscall 212 */
793# endif
794# if defined(__NR_lchown32)
795 case __NR_lchown32: /* syscall 198 */
796# endif
797 case __NR_chown: /* syscall 16 */
798 /* int chown(const char *path, uid_t owner, gid_t group); */
799 if (VG_(clo_trace_syscalls))
800 VG_(printf)("chown ( %p, 0x%x, 0x%x )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +0000801 must_be_readable_asciiz( tst, "chown(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +0000802 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000803 break;
804
805 case __NR_close: /* syscall 6 */
806 /* int close(int fd); */
807 if (VG_(clo_trace_syscalls))
808 VG_(printf)("close ( %d )\n",arg1);
809 /* Detect and negate attempts by the client to close Valgrind's
810 logfile fd ... */
811 if (arg1 == VG_(clo_logfile_fd)) {
812 VG_(message)(Vg_UserMsg,
813 "Warning: client attempted to close "
814 "Valgrind's logfile fd (%d).",
815 VG_(clo_logfile_fd));
816 VG_(message)(Vg_UserMsg,
817 " Use --logfile-fd=<number> to select an "
818 "alternative logfile fd." );
819 } else {
sewardj2e93c502002-04-12 11:12:52 +0000820 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000821 }
822 break;
823
824 case __NR_dup: /* syscall 41 */
825 /* int dup(int oldfd); */
826 if (VG_(clo_trace_syscalls))
827 VG_(printf)("dup ( %d ) --> ", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000828 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000829 if (VG_(clo_trace_syscalls))
830 VG_(printf)("%d\n", res);
831 break;
832
833 case __NR_dup2: /* syscall 63 */
834 /* int dup2(int oldfd, int newfd); */
835 if (VG_(clo_trace_syscalls))
836 VG_(printf)("dup2 ( %d, %d ) ...\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +0000837 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000838 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +0000839 VG_(printf)("SYSCALL[%d] dup2 ( %d, %d ) = %d\n",
840 VG_(getpid)(),
sewardjde4a1d02002-03-22 01:27:54 +0000841 arg1, arg2, res);
842 break;
843
844 case __NR_fcntl: /* syscall 55 */
sewardj2e93c502002-04-12 11:12:52 +0000845 /* int fcntl(int fd, int cmd, int arg); */
sewardjde4a1d02002-03-22 01:27:54 +0000846 if (VG_(clo_trace_syscalls))
sewardj2e93c502002-04-12 11:12:52 +0000847 VG_(printf)("fcntl ( %d, %d, %d )\n",arg1,arg2,arg3);
848 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000849 break;
850
851 case __NR_fchdir: /* syscall 133 */
852 /* int fchdir(int fd); */
853 if (VG_(clo_trace_syscalls))
854 VG_(printf)("fchdir ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000855 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000856 break;
857
sewardj2f0de322002-03-24 10:17:25 +0000858# if defined(__NR_fchown32)
859 case __NR_fchown32: /* syscall 207 */
860# endif
861 case __NR_fchown: /* syscall 95 */
862 /* int fchown(int filedes, uid_t owner, gid_t group); */
863 if (VG_(clo_trace_syscalls))
864 VG_(printf)("fchown ( %d, %d, %d )\n", arg1,arg2,arg3);
sewardj2e93c502002-04-12 11:12:52 +0000865 KERNEL_DO_SYSCALL(tid,res);
sewardj2f0de322002-03-24 10:17:25 +0000866 break;
867
sewardjde4a1d02002-03-22 01:27:54 +0000868 case __NR_fchmod: /* syscall 94 */
869 /* int fchmod(int fildes, mode_t mode); */
870 if (VG_(clo_trace_syscalls))
871 VG_(printf)("fchmod ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +0000872 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000873 break;
sewardj2f0de322002-03-24 10:17:25 +0000874
sewardjde4a1d02002-03-22 01:27:54 +0000875# if defined(__NR_fcntl64)
876 case __NR_fcntl64: /* syscall 221 */
877 /* I don't know what the prototype for this is supposed to be. */
878 /* ??? int fcntl(int fd, int cmd); */
879 if (VG_(clo_trace_syscalls))
880 VG_(printf)("fcntl64 (?!) ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +0000881 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000882 break;
883# endif
884
885 case __NR_fstat: /* syscall 108 */
886 /* int fstat(int filedes, struct stat *buf); */
887 if (VG_(clo_trace_syscalls))
888 VG_(printf)("fstat ( %d, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000889 must_be_writable( tst, "fstat", arg2, sizeof(struct stat) );
sewardj2e93c502002-04-12 11:12:52 +0000890 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000891 if (!VG_(is_kerror)(res))
892 make_readable( arg2, sizeof(struct stat) );
893 break;
894
895 case __NR_vfork: /* syscall 190 */
896 /* pid_t vfork(void); */
897 if (VG_(clo_trace_syscalls))
898 VG_(printf)("vfork ( ) ... becomes ... ");
899 /* KLUDGE: we prefer to do a fork rather than vfork.
900 vfork gives a SIGSEGV, and the stated semantics looks
901 pretty much impossible for us. */
sewardj2e93c502002-04-12 11:12:52 +0000902 tst->m_eax = __NR_fork;
sewardjde4a1d02002-03-22 01:27:54 +0000903 /* fall through ... */
904 case __NR_fork: /* syscall 2 */
905 /* pid_t fork(void); */
906 if (VG_(clo_trace_syscalls))
907 VG_(printf)("fork ()\n");
sewardj2e93c502002-04-12 11:12:52 +0000908 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000909 break;
910
911 case __NR_fsync: /* syscall 118 */
912 /* int fsync(int fd); */
913 if (VG_(clo_trace_syscalls))
914 VG_(printf)("fsync ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +0000915 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000916 break;
917
918 case __NR_ftruncate: /* syscall 93 */
919 /* int ftruncate(int fd, size_t length); */
920 if (VG_(clo_trace_syscalls))
921 VG_(printf)("ftruncate ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +0000922 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000923 break;
924
sewardj2f0de322002-03-24 10:17:25 +0000925# if defined(__NR_ftruncate64)
926 case __NR_ftruncate64: /* syscall 194 */
927 /* int ftruncate64(int fd, off64_t length); */
928 if (VG_(clo_trace_syscalls))
929 VG_(printf)("ftruncate64 ( %d, %lld )\n",
930 arg1,arg2|((long long) arg3 << 32));
sewardj2e93c502002-04-12 11:12:52 +0000931 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000932 break;
933# endif
934
935 case __NR_getdents: /* syscall 141 */
936 /* int getdents(unsigned int fd, struct dirent *dirp,
937 unsigned int count); */
938 if (VG_(clo_trace_syscalls))
939 VG_(printf)("getdents ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +0000940 must_be_writable( tst, "getdents(dirp)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000941 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000942 if (!VG_(is_kerror)(res) && res > 0)
943 make_readable( arg2, res );
944 break;
945
946# if defined(__NR_getdents64)
947 case __NR_getdents64: /* syscall 220 */
948 /* int getdents(unsigned int fd, struct dirent64 *dirp,
949 unsigned int count); */
950 if (VG_(clo_trace_syscalls))
951 VG_(printf)("getdents64 ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +0000952 must_be_writable( tst, "getdents64(dirp)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +0000953 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000954 if (!VG_(is_kerror)(res) && res > 0)
955 make_readable( arg2, res );
956 break;
957# endif
958
959# if defined(__NR_getgroups32)
960 case __NR_getgroups32: /* syscall 205 */
961# endif
962 case __NR_getgroups: /* syscall 80 */
963 /* int getgroups(int size, gid_t list[]); */
964 if (VG_(clo_trace_syscalls))
965 VG_(printf)("getgroups ( %d, %p )\n", arg1, arg2);
966 if (arg1 > 0)
sewardj8c824512002-04-14 04:16:48 +0000967 must_be_writable ( tst, "getgroups(list)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +0000968 arg1 * sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +0000969 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000970 if (arg1 > 0 && !VG_(is_kerror)(res) && res > 0)
971 make_readable ( arg2, res * sizeof(gid_t) );
972 break;
973
974 case __NR_getcwd: /* syscall 183 */
975 /* char *getcwd(char *buf, size_t size); */
976 if (VG_(clo_trace_syscalls))
977 VG_(printf)("getcwd ( %p, %d )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +0000978 must_be_writable( tst, "getcwd(buf)", arg1, arg2 );
sewardj2e93c502002-04-12 11:12:52 +0000979 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000980 if (!VG_(is_kerror)(res) && res != (Addr)NULL)
981 make_readable ( arg1, arg2 );
982 /* Not really right -- really we should have the asciiz
983 string starting at arg1 readable, or up to arg2 bytes,
984 whichever finishes first. */
985 break;
986
987 case __NR_geteuid: /* syscall 49 */
988 /* uid_t geteuid(void); */
989 if (VG_(clo_trace_syscalls))
990 VG_(printf)("geteuid ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000991 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +0000992 break;
993
994# if defined(__NR_geteuid32)
995 case __NR_geteuid32: /* syscall 201 */
996 /* ?? uid_t geteuid32(void); */
997 if (VG_(clo_trace_syscalls))
998 VG_(printf)("geteuid32(?) ( )\n");
sewardj2e93c502002-04-12 11:12:52 +0000999 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001000 break;
1001# endif
1002
1003 case __NR_getegid: /* syscall 50 */
1004 /* gid_t getegid(void); */
1005 if (VG_(clo_trace_syscalls))
1006 VG_(printf)("getegid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001007 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001008 break;
1009
1010# if defined(__NR_getegid32)
1011 case __NR_getegid32: /* syscall 202 */
1012 /* gid_t getegid32(void); */
1013 if (VG_(clo_trace_syscalls))
1014 VG_(printf)("getegid32 ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001015 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001016 break;
1017# endif
1018
1019 case __NR_getgid: /* syscall 47 */
1020 /* gid_t getgid(void); */
1021 if (VG_(clo_trace_syscalls))
1022 VG_(printf)("getgid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001023 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001024 break;
1025
1026# if defined(__NR_getgid32)
1027 case __NR_getgid32: /* syscall 200 */
1028 /* gid_t getgid32(void); */
1029 if (VG_(clo_trace_syscalls))
1030 VG_(printf)("getgid32 ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001031 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001032 break;
1033# endif
1034
1035 case __NR_getpid: /* syscall 20 */
1036 /* pid_t getpid(void); */
1037 if (VG_(clo_trace_syscalls))
1038 VG_(printf)("getpid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001039 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001040 break;
1041
1042 case __NR_getpgid: /* syscall 132 */
1043 /* pid_t getpgid(pid_t pid); */
1044 if (VG_(clo_trace_syscalls))
1045 VG_(printf)("getpgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00001046 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001047 break;
1048
1049 case __NR_getpgrp: /* syscall 65 */
1050 /* pid_t getpprp(void); */
1051 if (VG_(clo_trace_syscalls))
1052 VG_(printf)("getpgrp ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001053 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001054 break;
1055
1056 case __NR_getppid: /* syscall 64 */
1057 /* pid_t getppid(void); */
1058 if (VG_(clo_trace_syscalls))
1059 VG_(printf)("getppid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00001060 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001061 break;
1062
1063 case __NR_getresgid: /* syscall 171 */
1064 /* int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); */
1065 if (VG_(clo_trace_syscalls))
1066 VG_(printf)("getresgid ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001067 must_be_writable ( tst, "getresgid(rgid)", arg1, sizeof(gid_t) );
1068 must_be_writable ( tst, "getresgid(egid)", arg2, sizeof(gid_t) );
1069 must_be_writable ( tst, "getresgid(sgid)", arg3, sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001070 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001071 if (!VG_(is_kerror)(res) && res == 0) {
1072 make_readable ( arg1, sizeof(gid_t) );
1073 make_readable ( arg2, sizeof(gid_t) );
1074 make_readable ( arg3, sizeof(gid_t) );
1075 }
1076 break;
1077
1078# if defined(__NR_getresgid32)
1079 case __NR_getresgid32: /* syscall 211 */
1080 /* int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); */
1081 if (VG_(clo_trace_syscalls))
1082 VG_(printf)("getresgid32 ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001083 must_be_writable ( tst, "getresgid32(rgid)", arg1, sizeof(gid_t) );
1084 must_be_writable ( tst, "getresgid32(egid)", arg2, sizeof(gid_t) );
1085 must_be_writable ( tst, "getresgid32(sgid)", arg3, sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001086 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001087 if (!VG_(is_kerror)(res) && res == 0) {
1088 make_readable ( arg1, sizeof(gid_t) );
1089 make_readable ( arg2, sizeof(gid_t) );
1090 make_readable ( arg3, sizeof(gid_t) );
1091 }
1092 break;
1093# endif
1094
1095 case __NR_getresuid: /* syscall 165 */
1096 /* int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); */
1097 if (VG_(clo_trace_syscalls))
1098 VG_(printf)("getresuid ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001099 must_be_writable ( tst, "getresuid(ruid)", arg1, sizeof(uid_t) );
1100 must_be_writable ( tst, "getresuid(euid)", arg2, sizeof(uid_t) );
1101 must_be_writable ( tst, "getresuid(suid)", arg3, sizeof(uid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001102 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001103 if (!VG_(is_kerror)(res) && res == 0) {
1104 make_readable ( arg1, sizeof(uid_t) );
1105 make_readable ( arg2, sizeof(uid_t) );
1106 make_readable ( arg3, sizeof(uid_t) );
1107 }
1108 break;
1109
1110# if defined(__NR_getresuid32)
1111 case __NR_getresuid32: /* syscall 209 */
1112 /* int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); */
1113 if (VG_(clo_trace_syscalls))
1114 VG_(printf)("getresuid32 ( %p, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00001115 must_be_writable ( tst, "getresuid32(ruid)", arg1, sizeof(uid_t) );
1116 must_be_writable ( tst, "getresuid32(euid)", arg2, sizeof(uid_t) );
1117 must_be_writable ( tst, "getresuid32(suid)", arg3, sizeof(uid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001118 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001119 if (!VG_(is_kerror)(res) && res == 0) {
1120 make_readable ( arg1, sizeof(uid_t) );
1121 make_readable ( arg2, sizeof(uid_t) );
1122 make_readable ( arg3, sizeof(uid_t) );
1123 }
1124 break;
1125# endif
1126
1127# if defined(__NR_ugetrlimit)
1128 case __NR_ugetrlimit: /* syscall 191 */
1129# endif
1130 case __NR_getrlimit: /* syscall 76 */
1131 /* int getrlimit (int resource, struct rlimit *rlim); */
1132 if (VG_(clo_trace_syscalls))
1133 VG_(printf)("getrlimit ( %d, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001134 must_be_writable( tst, "getrlimit(rlim)", arg2,
1135 sizeof(struct rlimit) );
sewardj2e93c502002-04-12 11:12:52 +00001136 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001137 if (!VG_(is_kerror)(res) && res == 0)
1138 make_readable( arg2, sizeof(struct rlimit) );
1139 break;
1140
1141 case __NR_getrusage: /* syscall 77 */
1142 /* int getrusage (int who, struct rusage *usage); */
1143 if (VG_(clo_trace_syscalls))
1144 VG_(printf)("getrusage ( %d, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001145 must_be_writable( tst, "getrusage(usage)", arg2,
1146 sizeof(struct rusage) );
sewardj2e93c502002-04-12 11:12:52 +00001147 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001148 if (!VG_(is_kerror)(res) && res == 0)
1149 make_readable(arg2, sizeof(struct rusage) );
1150 break;
1151
1152 case __NR_gettimeofday: /* syscall 78 */
1153 /* int gettimeofday(struct timeval *tv, struct timezone *tz); */
1154 if (VG_(clo_trace_syscalls))
1155 VG_(printf)("gettimeofday ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001156 must_be_writable( tst, "gettimeofday(tv)", arg1,
1157 sizeof(struct timeval) );
sewardjde4a1d02002-03-22 01:27:54 +00001158 if (arg2 != 0)
sewardj8c824512002-04-14 04:16:48 +00001159 must_be_writable( tst, "gettimeofday(tz)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00001160 sizeof(struct timezone) );
sewardj2e93c502002-04-12 11:12:52 +00001161 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001162 if (!VG_(is_kerror)(res) && res == 0) {
1163 make_readable( arg1, sizeof(struct timeval) );
1164 if (arg2 != 0)
1165 make_readable( arg2, sizeof(struct timezone) );
1166 }
1167 break;
1168
1169 case __NR_getuid: /* syscall 24 */
1170 /* uid_t getuid(void); */
1171 if (VG_(clo_trace_syscalls))
1172 VG_(printf)("getuid ( )\n");
sewardj2e93c502002-04-12 11:12:52 +00001173 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001174 break;
1175
1176# if defined(__NR_getuid32)
1177 case __NR_getuid32: /* syscall 199 */
1178 /* ???uid_t getuid32(void); */
1179 if (VG_(clo_trace_syscalls))
1180 VG_(printf)("getuid32 ( )\n");
sewardj2e93c502002-04-12 11:12:52 +00001181 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001182 break;
1183# endif
1184
1185 case __NR_ipc: /* syscall 117 */
1186 /* int ipc ( unsigned int call, int first, int second,
1187 int third, void *ptr, long fifth); */
1188 {
sewardj2e93c502002-04-12 11:12:52 +00001189 UInt arg6 = tst->m_ebp;
sewardjde4a1d02002-03-22 01:27:54 +00001190
1191 if (VG_(clo_trace_syscalls))
1192 VG_(printf)("ipc ( %d, %d, %d, %d, %p, %d )\n",
1193 arg1,arg2,arg3,arg4,arg5,arg6);
1194 switch (arg1 /* call */) {
1195 case 1: /* IPCOP_semop */
sewardj8c824512002-04-14 04:16:48 +00001196 must_be_readable ( tst, "semop(sops)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001197 arg3 * sizeof(struct sembuf) );
sewardj2e93c502002-04-12 11:12:52 +00001198 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001199 break;
sewardj5b9e3502002-03-29 04:35:08 +00001200 case 2: /* IPCOP_semget */
1201 case 3: /* IPCOP_semctl */
sewardj2e93c502002-04-12 11:12:52 +00001202 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001203 break;
1204 case 11: /* IPCOP_msgsnd */
1205 {
1206 struct msgbuf *msgp = (struct msgbuf *)arg5;
1207 Int msgsz = arg3;
1208
sewardj8c824512002-04-14 04:16:48 +00001209 must_be_readable ( tst, "msgsnd(msgp->mtype)",
sewardj5b9e3502002-03-29 04:35:08 +00001210 (UInt)&msgp->mtype, sizeof(msgp->mtype) );
sewardj8c824512002-04-14 04:16:48 +00001211 must_be_readable ( tst, "msgsnd(msgp->mtext)",
sewardj5b9e3502002-03-29 04:35:08 +00001212 (UInt)msgp->mtext, msgsz );
1213
sewardj2e93c502002-04-12 11:12:52 +00001214 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001215 break;
1216 }
1217 case 12: /* IPCOP_msgrcv */
1218 {
sewardj59c255c2002-04-27 02:06:15 +00001219 struct msgbuf *msgp;
sewardj5b9e3502002-03-29 04:35:08 +00001220 Int msgsz = arg3;
sewardj59c255c2002-04-27 02:06:15 +00001221
1222 msgp = (struct msgbuf *)safe_dereference(
1223 (Addr) (&((struct ipc_kludge *)arg5)->msgp), 0 );
sewardj5b9e3502002-03-29 04:35:08 +00001224
sewardj59c255c2002-04-27 02:06:15 +00001225 must_be_writable ( tst, "msgrcv(msgp->mtype)",
sewardj5b9e3502002-03-29 04:35:08 +00001226 (UInt)&msgp->mtype, sizeof(msgp->mtype) );
sewardj59c255c2002-04-27 02:06:15 +00001227 must_be_writable ( tst, "msgrcv(msgp->mtext)",
sewardj5b9e3502002-03-29 04:35:08 +00001228 (UInt)msgp->mtext, msgsz );
1229
sewardj2e93c502002-04-12 11:12:52 +00001230 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001231
1232 if ( !VG_(is_kerror)(res) && res > 0 ) {
1233 make_readable ( (UInt)&msgp->mtype, sizeof(msgp->mtype) );
1234 make_readable ( (UInt)msgp->mtext, res );
1235 }
1236 break;
1237 }
1238 case 13: /* IPCOP_msgget */
sewardj2e93c502002-04-12 11:12:52 +00001239 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001240 break;
1241 case 14: /* IPCOP_msgctl */
1242 {
1243 switch (arg3 /* cmd */) {
1244 case IPC_STAT:
sewardj8c824512002-04-14 04:16:48 +00001245 must_be_writable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001246 sizeof(struct msqid_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001247 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001248 if ( !VG_(is_kerror)(res) && res > 0 ) {
1249 make_readable ( arg5, sizeof(struct msqid_ds) );
1250 }
1251 break;
1252 case IPC_SET:
sewardj8c824512002-04-14 04:16:48 +00001253 must_be_readable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001254 sizeof(struct msqid_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001255 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001256 break;
sewardjc9add3b2002-04-16 01:58:19 +00001257# if defined(IPC_64)
sewardj5b9e3502002-03-29 04:35:08 +00001258 case IPC_STAT|IPC_64:
sewardj8c824512002-04-14 04:16:48 +00001259 must_be_writable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001260 sizeof(struct msqid64_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001261 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001262 if ( !VG_(is_kerror)(res) && res > 0 ) {
1263 make_readable ( arg5, sizeof(struct msqid64_ds) );
1264 }
1265 break;
sewardjc9add3b2002-04-16 01:58:19 +00001266# endif
1267# if defined(IPC_64)
sewardj5b9e3502002-03-29 04:35:08 +00001268 case IPC_SET|IPC_64:
sewardj8c824512002-04-14 04:16:48 +00001269 must_be_readable ( tst, "msgctl(buf)", arg5,
sewardj5b9e3502002-03-29 04:35:08 +00001270 sizeof(struct msqid64_ds) );
sewardj2e93c502002-04-12 11:12:52 +00001271 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001272 break;
sewardjc9add3b2002-04-16 01:58:19 +00001273# endif
sewardj5b9e3502002-03-29 04:35:08 +00001274 default:
sewardj2e93c502002-04-12 11:12:52 +00001275 KERNEL_DO_SYSCALL(tid,res);
sewardj5b9e3502002-03-29 04:35:08 +00001276 break;
1277 }
1278 break;
1279 }
sewardjde4a1d02002-03-22 01:27:54 +00001280 case 21: /* IPCOP_shmat */
1281 {
1282 Int shmid = arg2;
1283 Int shmflag = arg3;
1284 UInt addr;
1285
sewardj2e93c502002-04-12 11:12:52 +00001286 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001287
1288 if ( VG_(is_kerror) ( res ) )
1289 break;
1290
1291 /* force readability. before the syscall it is
1292 * indeed uninitialized, as can be seen in
1293 * glibc/sysdeps/unix/sysv/linux/shmat.c */
1294 make_readable ( arg4, sizeof( ULong ) );
1295
1296 addr = safe_dereference ( arg4, 0 );
1297 if ( addr > 0 ) {
1298 UInt segmentSize = get_shm_size ( shmid );
1299 if ( segmentSize > 0 ) {
1300 if ( shmflag & SHM_RDONLY )
1301 make_readable ( addr, segmentSize );
1302 else
1303 make_readwritable ( addr, segmentSize );
1304 }
1305 }
1306 break;
1307 }
1308 case 22: /* IPCOP_shmdt */
sewardj2e93c502002-04-12 11:12:52 +00001309 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001310 /* ### FIXME: this should call make_noaccess on the
1311 * area passed to shmdt. But there's no way to
1312 * figure out the size of the shared memory segment
1313 * just from the address... Maybe we want to keep a
1314 * copy of the exiting mappings inside valgrind? */
1315 break;
1316 case 23: /* IPCOP_shmget */
sewardj2e93c502002-04-12 11:12:52 +00001317 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001318 break;
1319 case 24: /* IPCOP_shmctl */
1320 {
1321 if ( arg3 > 0 ) {
sewardj8c824512002-04-14 04:16:48 +00001322 must_be_readable ( tst, "shmctl(buf)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001323 sizeof( struct shmid_ds ) );
1324
1325 if ( arg2 == SHM_STAT )
sewardj8c824512002-04-14 04:16:48 +00001326 must_be_writable( tst, "shmctl(IPC_STAT,buf)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001327 sizeof( struct shmid_ds ) );
1328 }
1329
sewardj2e93c502002-04-12 11:12:52 +00001330 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001331 break;
1332 }
1333 default:
1334 VG_(message)(Vg_DebugMsg,
1335 "FATAL: unhandled syscall(ipc) %d",
1336 arg1 );
1337 VG_(panic)("... bye!\n");
1338 break; /*NOTREACHED*/
1339 }
1340 }
1341 break;
1342
1343 case __NR_ioctl: /* syscall 54 */
1344 /* int ioctl(int d, int request, ...)
1345 [The "third" argument is traditionally char *argp,
1346 and will be so named for this discussion.]
1347 */
1348 /*
1349 VG_(message)(
1350 Vg_DebugMsg,
1351 "is an IOCTL, request = 0x%x, d = %d, argp = 0x%x",
1352 arg2,arg1,arg3);
1353 */
1354 if (VG_(clo_trace_syscalls))
1355 VG_(printf)("ioctl ( %d, 0x%x, %p )\n",arg1,arg2,arg3);
1356 switch (arg2 /* request */) {
1357 case TCSETS:
1358 case TCSETSW:
1359 case TCSETSF:
sewardj8c824512002-04-14 04:16:48 +00001360 must_be_readable( tst, "ioctl(TCSETSW)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001361 VKI_SIZEOF_STRUCT_TERMIOS );
sewardj2e93c502002-04-12 11:12:52 +00001362 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001363 break;
1364 case TCGETS:
sewardj8c824512002-04-14 04:16:48 +00001365 must_be_writable( tst, "ioctl(TCGETS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001366 VKI_SIZEOF_STRUCT_TERMIOS );
sewardj2e93c502002-04-12 11:12:52 +00001367 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001368 if (!VG_(is_kerror)(res) && res == 0)
1369 make_readable ( arg3, VKI_SIZEOF_STRUCT_TERMIOS );
1370 break;
sewardj2f0de322002-03-24 10:17:25 +00001371 case TCSETA:
sewardj8c824512002-04-14 04:16:48 +00001372 must_be_readable( tst, "ioctl(TCSETA)", arg3,
sewardj2f0de322002-03-24 10:17:25 +00001373 VKI_SIZEOF_STRUCT_TERMIO );
sewardj2e93c502002-04-12 11:12:52 +00001374 KERNEL_DO_SYSCALL(tid,res);
sewardj2f0de322002-03-24 10:17:25 +00001375 break;
1376 case TCGETA:
sewardj8c824512002-04-14 04:16:48 +00001377 must_be_writable( tst, "ioctl(TCGETA)", arg3,
sewardj2f0de322002-03-24 10:17:25 +00001378 VKI_SIZEOF_STRUCT_TERMIO );
sewardj2e93c502002-04-12 11:12:52 +00001379 KERNEL_DO_SYSCALL(tid,res);
sewardj2f0de322002-03-24 10:17:25 +00001380 if (!VG_(is_kerror)(res) && res == 0)
1381 make_readable ( arg3, VKI_SIZEOF_STRUCT_TERMIO );
1382 break;
sewardjde4a1d02002-03-22 01:27:54 +00001383 case TCSBRK:
1384 case TCSBRKP:
1385 case TCFLSH:
1386 /* These just take an int by value */
sewardj2e93c502002-04-12 11:12:52 +00001387 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001388 break;
1389 case TIOCGWINSZ:
sewardj8c824512002-04-14 04:16:48 +00001390 must_be_writable( tst, "ioctl(TIOCGWINSZ)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001391 sizeof(struct winsize) );
sewardj2e93c502002-04-12 11:12:52 +00001392 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001393 if (!VG_(is_kerror)(res) && res == 0)
1394 make_readable ( arg3, sizeof(struct winsize) );
1395 break;
1396 case TIOCSWINSZ:
sewardj8c824512002-04-14 04:16:48 +00001397 must_be_readable( tst, "ioctl(TIOCSWINSZ)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001398 sizeof(struct winsize) );
sewardj2e93c502002-04-12 11:12:52 +00001399 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001400 break;
sewardj19fe3d02002-03-29 04:39:00 +00001401 case TIOCGPGRP:
1402 /* Get process group ID for foreground processing group. */
sewardj8c824512002-04-14 04:16:48 +00001403 must_be_writable( tst, "ioctl(TIOCGPGRP)", arg3,
sewardj19fe3d02002-03-29 04:39:00 +00001404 sizeof(pid_t) );
sewardj2e93c502002-04-12 11:12:52 +00001405 KERNEL_DO_SYSCALL(tid,res);
sewardj19fe3d02002-03-29 04:39:00 +00001406 if (!VG_(is_kerror)(res) && res == 0)
1407 make_readable ( arg3, sizeof(pid_t) );
sewardjde4a1d02002-03-22 01:27:54 +00001408 case TIOCGPTN: /* Get Pty Number (of pty-mux device) */
sewardj8c824512002-04-14 04:16:48 +00001409 must_be_writable(tst, "ioctl(TIOCGPTN)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001410 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001411 if (!VG_(is_kerror)(res) && res == 0)
1412 make_readable ( arg3, sizeof(int));
1413 break;
sewardj73f1f072002-03-29 14:22:46 +00001414 case TIOCSCTTY:
1415 /* Just takes an int value. */
sewardj2e93c502002-04-12 11:12:52 +00001416 KERNEL_DO_SYSCALL(tid,res);
sewardj73f1f072002-03-29 14:22:46 +00001417 break;
sewardjde4a1d02002-03-22 01:27:54 +00001418 case TIOCSPTLCK: /* Lock/unlock Pty */
sewardj8c824512002-04-14 04:16:48 +00001419 must_be_readable( tst, "ioctl(TIOCSPTLCK)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001420 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001421 break;
1422 case FIONBIO:
sewardj8c824512002-04-14 04:16:48 +00001423 must_be_readable( tst, "ioctl(FIONBIO)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001424 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001425 break;
1426 case FIOASYNC:
sewardj8c824512002-04-14 04:16:48 +00001427 must_be_readable( tst, "ioctl(FIOASYNC)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001428 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001429 break;
1430 case FIONREAD:
sewardj8c824512002-04-14 04:16:48 +00001431 must_be_writable( tst, "ioctl(FIONREAD)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001432 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001433 if (!VG_(is_kerror)(res) && res == 0)
1434 make_readable( arg3, sizeof(int) );
1435 break;
1436
1437 /* If you get compilation problems here, change the #if
1438 1 to #if 0 and get rid of <scsi/sg.h> in
1439 vg_unsafe.h. */
1440# if 1
1441 case SG_SET_COMMAND_Q:
sewardj8c824512002-04-14 04:16:48 +00001442 must_be_readable( tst, "ioctl(SG_SET_COMMAND_Q)",
1443 arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001444 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001445 break;
1446# if defined(SG_IO)
1447 case SG_IO:
sewardj8c824512002-04-14 04:16:48 +00001448 must_be_writable( tst, "ioctl(SG_IO)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001449 sizeof(struct sg_io_hdr) );
sewardj2e93c502002-04-12 11:12:52 +00001450 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001451 if (!VG_(is_kerror)(res) && res == 0)
1452 make_readable (arg3, sizeof(struct sg_io_hdr));
1453 break;
1454# endif /* SG_IO */
1455 case SG_GET_SCSI_ID:
1456 /* Note: sometimes sg_scsi_id is called sg_scsi_id_t */
sewardj8c824512002-04-14 04:16:48 +00001457 must_be_writable( tst, "ioctl(SG_GET_SCSI_ID)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001458 sizeof(struct sg_scsi_id) );
sewardj2e93c502002-04-12 11:12:52 +00001459 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001460 if (!VG_(is_kerror)(res) && res == 0)
1461 make_readable (arg3, sizeof(struct sg_scsi_id));
1462 break;
1463 case SG_SET_RESERVED_SIZE:
sewardj8c824512002-04-14 04:16:48 +00001464 must_be_readable( tst, "ioctl(SG_SET_RESERVED_SIZE)",
sewardjde4a1d02002-03-22 01:27:54 +00001465 arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001466 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001467 break;
1468 case SG_SET_TIMEOUT:
sewardj8c824512002-04-14 04:16:48 +00001469 must_be_readable( tst, "ioctl(SG_SET_TIMEOUT)", arg3,
1470 sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001471 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001472 break;
1473 case SG_GET_RESERVED_SIZE:
sewardj8c824512002-04-14 04:16:48 +00001474 must_be_writable( tst, "ioctl(SG_GET_RESERVED_SIZE)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001475 sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001476 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001477 if (!VG_(is_kerror)(res) && res == 0)
1478 make_readable (arg3, sizeof(int));
1479 break;
1480 case SG_GET_TIMEOUT:
sewardj8c824512002-04-14 04:16:48 +00001481 must_be_writable( tst, "ioctl(SG_GET_TIMEOUT)", arg3,
1482 sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001483 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001484 if (!VG_(is_kerror)(res) && res == 0)
1485 make_readable (arg3, sizeof(int));
1486 break;
1487 case SG_GET_VERSION_NUM:
sewardj8c824512002-04-14 04:16:48 +00001488 must_be_readable( tst, "ioctl(SG_GET_VERSION_NUM)",
sewardjde4a1d02002-03-22 01:27:54 +00001489 arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001490 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001491 break;
1492# endif
1493
1494 case IIOCGETCPS:
1495 /* In early 2.4 kernels, ISDN_MAX_CHANNELS was only defined
1496 * when KERNEL was. I never saw a larger value than 64 though */
1497# ifndef ISDN_MAX_CHANNELS
1498# define ISDN_MAX_CHANNELS 64
1499# endif
sewardj8c824512002-04-14 04:16:48 +00001500 must_be_writable( tst, "ioctl(IIOCGETCPS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001501 ISDN_MAX_CHANNELS
1502 * 2 * sizeof(unsigned long) );
sewardj2e93c502002-04-12 11:12:52 +00001503 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001504 if (!VG_(is_kerror)(res) && res == 0)
1505 make_readable ( arg3, ISDN_MAX_CHANNELS
1506 * 2 * sizeof(unsigned long) );
1507 break;
1508 case IIOCNETGPN:
sewardj8c824512002-04-14 04:16:48 +00001509 must_be_readable( tst, "ioctl(IIOCNETGPN)",
sewardjde4a1d02002-03-22 01:27:54 +00001510 (UInt)&((isdn_net_ioctl_phone *)arg3)->name,
1511 sizeof(((isdn_net_ioctl_phone *)arg3)->name) );
sewardj8c824512002-04-14 04:16:48 +00001512 must_be_writable( tst, "ioctl(IIOCNETGPN)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001513 sizeof(isdn_net_ioctl_phone) );
sewardj2e93c502002-04-12 11:12:52 +00001514 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001515 if (!VG_(is_kerror)(res) && res == 0)
1516 make_readable ( arg3, sizeof(isdn_net_ioctl_phone) );
1517 break;
1518
1519 /* These all use struct ifreq AFAIK */
1520 case SIOCGIFINDEX:
1521 case SIOCGIFFLAGS: /* get flags */
1522 case SIOCGIFHWADDR: /* Get hardware address */
1523 case SIOCGIFMTU: /* get MTU size */
1524 case SIOCGIFADDR: /* get PA address */
1525 case SIOCGIFNETMASK: /* get network PA mask */
1526 case SIOCGIFMETRIC: /* get metric */
1527 case SIOCGIFMAP: /* Get device parameters */
1528 case SIOCGIFTXQLEN: /* Get the tx queue length */
1529 case SIOCGIFDSTADDR: /* get remote PA address */
1530 case SIOCGIFBRDADDR: /* get broadcast PA address */
1531 case SIOCGIFNAME: /* get iface name */
sewardj8c824512002-04-14 04:16:48 +00001532 must_be_writable(tst, "ioctl(SIOCGIFINDEX)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001533 sizeof(struct ifreq));
sewardj2e93c502002-04-12 11:12:52 +00001534 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001535 if (!VG_(is_kerror)(res) && res == 0)
1536 make_readable (arg3, sizeof(struct ifreq));
1537 break;
1538 case SIOCGIFCONF: /* get iface list */
1539 /* WAS:
1540 must_be_writable("ioctl(SIOCGIFCONF)", arg3,
1541 sizeof(struct ifconf));
sewardj2e93c502002-04-12 11:12:52 +00001542 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001543 if (!VG_(is_kerror)(res) && res == 0)
1544 make_readable (arg3, sizeof(struct ifconf));
1545 */
sewardj8c824512002-04-14 04:16:48 +00001546 must_be_readable(tst, "ioctl(SIOCGIFCONF)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001547 sizeof(struct ifconf));
1548 if ( arg3 ) {
1549 // TODO len must be readable and writable
1550 // buf pointer only needs to be readable
1551 struct ifconf *ifc = (struct ifconf *) arg3;
sewardj8c824512002-04-14 04:16:48 +00001552 must_be_writable(tst, "ioctl(SIOCGIFCONF).ifc_buf",
sewardjde4a1d02002-03-22 01:27:54 +00001553 (Addr)(ifc->ifc_buf), (UInt)(ifc->ifc_len) );
1554 }
sewardj2e93c502002-04-12 11:12:52 +00001555 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001556 if (!VG_(is_kerror)(res) && res == 0 && arg3 ) {
1557 struct ifconf *ifc = (struct ifconf *) arg3;
1558 make_readable ( (Addr)(ifc->ifc_buf), (UInt)(ifc->ifc_len) );
1559 }
1560 break;
1561 case SIOCGSTAMP:
sewardj8c824512002-04-14 04:16:48 +00001562 must_be_writable(tst, "ioctl(SIOCGSTAMP)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001563 sizeof(struct timeval));
sewardj2e93c502002-04-12 11:12:52 +00001564 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001565 if (!VG_(is_kerror)(res) && res == 0)
1566 make_readable (arg3, sizeof(struct timeval));
1567 break;
1568 case SIOCGRARP: /* get RARP table entry */
1569 case SIOCGARP: /* get ARP table entry */
sewardj8c824512002-04-14 04:16:48 +00001570 must_be_writable(tst, "ioctl(SIOCGARP)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001571 sizeof(struct arpreq));
sewardj2e93c502002-04-12 11:12:52 +00001572 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001573 if (!VG_(is_kerror)(res) && res == 0)
1574 make_readable (arg3, sizeof(struct arpreq));
1575 break;
1576
1577 case SIOCSIFFLAGS: /* set flags */
1578 case SIOCSIFMAP: /* Set device parameters */
1579 case SIOCSIFTXQLEN: /* Set the tx queue length */
1580 case SIOCSIFDSTADDR: /* set remote PA address */
1581 case SIOCSIFBRDADDR: /* set broadcast PA address */
1582 case SIOCSIFNETMASK: /* set network PA mask */
1583 case SIOCSIFMETRIC: /* set metric */
1584 case SIOCSIFADDR: /* set PA address */
1585 case SIOCSIFMTU: /* set MTU size */
1586 case SIOCSIFHWADDR: /* set hardware address */
sewardj8c824512002-04-14 04:16:48 +00001587 must_be_readable(tst,"ioctl(SIOCSIFFLAGS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001588 sizeof(struct ifreq));
sewardj2e93c502002-04-12 11:12:52 +00001589 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001590 break;
1591 /* Routing table calls. */
1592 case SIOCADDRT: /* add routing table entry */
1593 case SIOCDELRT: /* delete routing table entry */
sewardj8c824512002-04-14 04:16:48 +00001594 must_be_readable(tst,"ioctl(SIOCADDRT/DELRT)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001595 sizeof(struct rtentry));
sewardj2e93c502002-04-12 11:12:52 +00001596 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001597 break;
1598
1599 /* RARP cache control calls. */
1600 case SIOCDRARP: /* delete RARP table entry */
1601 case SIOCSRARP: /* set RARP table entry */
1602 /* ARP cache control calls. */
1603 case SIOCSARP: /* set ARP table entry */
1604 case SIOCDARP: /* delete ARP table entry */
sewardj8c824512002-04-14 04:16:48 +00001605 must_be_readable(tst, "ioctl(SIOCSIFFLAGS)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001606 sizeof(struct ifreq));
sewardj2e93c502002-04-12 11:12:52 +00001607 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001608 break;
1609
1610 case SIOCSPGRP:
sewardj8c824512002-04-14 04:16:48 +00001611 must_be_readable( tst, "ioctl(SIOCSPGRP)", arg3, sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00001612 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001613 break;
1614
1615 /* linux/soundcard interface (OSS) */
1616 case SNDCTL_SEQ_GETOUTCOUNT:
1617 case SNDCTL_SEQ_GETINCOUNT:
1618 case SNDCTL_SEQ_PERCMODE:
1619 case SNDCTL_SEQ_TESTMIDI:
1620 case SNDCTL_SEQ_RESETSAMPLES:
1621 case SNDCTL_SEQ_NRSYNTHS:
1622 case SNDCTL_SEQ_NRMIDIS:
1623 case SNDCTL_SEQ_GETTIME:
1624 case SNDCTL_DSP_GETFMTS:
1625 case SNDCTL_DSP_GETTRIGGER:
1626 case SNDCTL_DSP_GETODELAY:
1627# if defined(SNDCTL_DSP_GETSPDIF)
1628 case SNDCTL_DSP_GETSPDIF:
1629# endif
1630 case SNDCTL_DSP_GETCAPS:
1631 case SOUND_PCM_READ_RATE:
1632 case SOUND_PCM_READ_CHANNELS:
1633 case SOUND_PCM_READ_BITS:
1634 case (SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
1635 case SOUND_PCM_READ_FILTER:
sewardj8c824512002-04-14 04:16:48 +00001636 must_be_writable(tst,"ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
1637 arg3,
sewardjde4a1d02002-03-22 01:27:54 +00001638 sizeof(int));
sewardj2e93c502002-04-12 11:12:52 +00001639 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001640 if (!VG_(is_kerror)(res) && res == 0)
1641 make_readable (arg3, sizeof(int));
1642 break;
1643 case SNDCTL_SEQ_CTRLRATE:
1644 case SNDCTL_DSP_SPEED:
1645 case SNDCTL_DSP_STEREO:
1646 case SNDCTL_DSP_GETBLKSIZE:
1647 case SNDCTL_DSP_CHANNELS:
1648 case SOUND_PCM_WRITE_FILTER:
1649 case SNDCTL_DSP_SUBDIVIDE:
1650 case SNDCTL_DSP_SETFRAGMENT:
sewardj8a5089d2002-03-24 11:43:56 +00001651# if defined(SNDCTL_DSP_GETCHANNELMASK)
sewardjde4a1d02002-03-22 01:27:54 +00001652 case SNDCTL_DSP_GETCHANNELMASK:
sewardj8a5089d2002-03-24 11:43:56 +00001653# endif
1654# if defined(SNDCTL_DSP_BIND_CHANNEL)
sewardjde4a1d02002-03-22 01:27:54 +00001655 case SNDCTL_DSP_BIND_CHANNEL:
sewardj8a5089d2002-03-24 11:43:56 +00001656# endif
sewardjde4a1d02002-03-22 01:27:54 +00001657 case SNDCTL_TMR_TIMEBASE:
1658 case SNDCTL_TMR_TEMPO:
1659 case SNDCTL_TMR_SOURCE:
1660 case SNDCTL_MIDI_PRETIME:
1661 case SNDCTL_MIDI_MPUMODE:
sewardj8c824512002-04-14 04:16:48 +00001662 must_be_readable(tst, "ioctl(SNDCTL_XXX|SOUND_XXX "
1663 "(SIOWR, int))",
sewardjde4a1d02002-03-22 01:27:54 +00001664 arg3, sizeof(int));
sewardj8c824512002-04-14 04:16:48 +00001665 must_be_writable(tst, "ioctl(SNDCTL_XXX|SOUND_XXX "
1666 "(SIOWR, int))",
sewardjde4a1d02002-03-22 01:27:54 +00001667 arg3, sizeof(int));
sewardj2e93c502002-04-12 11:12:52 +00001668 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001669 break;
1670 case SNDCTL_DSP_GETOSPACE:
1671 case SNDCTL_DSP_GETISPACE:
sewardj8c824512002-04-14 04:16:48 +00001672 must_be_writable(tst,
1673 "ioctl(SNDCTL_XXX|SOUND_XXX "
sewardjde4a1d02002-03-22 01:27:54 +00001674 "(SIOR, audio_buf_info))", arg3,
1675 sizeof(audio_buf_info));
sewardj2e93c502002-04-12 11:12:52 +00001676 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001677 if (!VG_(is_kerror)(res) && res == 0)
1678 make_readable (arg3, sizeof(audio_buf_info));
1679 break;
1680 case SNDCTL_DSP_SETTRIGGER:
sewardj8c824512002-04-14 04:16:48 +00001681 must_be_readable(tst, "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
sewardjde4a1d02002-03-22 01:27:54 +00001682 arg3, sizeof(int));
sewardj2e93c502002-04-12 11:12:52 +00001683 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001684 break;
sewardj0aa4c252002-04-27 02:20:14 +00001685
1686 /* Real Time Clock (/dev/rtc) ioctls */
1687 case RTC_UIE_ON:
1688 case RTC_UIE_OFF:
1689 case RTC_AIE_ON:
1690 case RTC_AIE_OFF:
1691 case RTC_PIE_ON:
1692 case RTC_PIE_OFF:
1693 case RTC_IRQP_SET:
1694 KERNEL_DO_SYSCALL(tid,res);
1695 break;
1696 case RTC_RD_TIME:
1697 case RTC_ALM_READ:
1698 must_be_writable(tst, "ioctl(RTC_RD_TIME/ALM_READ)", arg3,
1699 sizeof(struct rtc_time));
1700 KERNEL_DO_SYSCALL(tid,res);
1701 if (!VG_(is_kerror) && res == 0)
1702 make_readable(arg3, sizeof(struct rtc_time));
1703 break;
1704 case RTC_ALM_SET:
1705 must_be_readable(tst, "ioctl(RTC_ALM_SET)", arg3,
1706 sizeof(struct rtc_time));
1707 KERNEL_DO_SYSCALL(tid,res);
1708 break;
1709 case RTC_IRQP_READ:
1710 must_be_writable(tst, "ioctl(RTC_IRQP_READ)", arg3,
1711 sizeof(unsigned long));
1712 KERNEL_DO_SYSCALL(tid,res);
1713 if(!VG_(is_kerror) && res == 0)
1714 make_readable(arg3, sizeof(unsigned long));
1715 break;
sewardjeea0f2e2002-04-27 02:28:19 +00001716
1717 /* CD ROM stuff (??) */
1718 case CDROMSUBCHNL:
1719 must_be_readable(tst, "ioctl(CDROMSUBCHNL (cdsc_format, char))",
1720 (int) &(((struct cdrom_subchnl *) arg3)->cdsc_format),
1721 sizeof(((struct cdrom_subchnl *) arg3)->cdsc_format));
1722 must_be_writable(tst, "ioctl(CDROMSUBCHNL)", arg3,
1723 sizeof(struct cdrom_subchnl));
1724 KERNEL_DO_SYSCALL(tid,res);
1725 if (!VG_(is_kerror)(res) && res == 0)
1726 make_readable (arg3, sizeof(struct cdrom_subchnl));
1727 break;
1728 case CDROMREADTOCHDR:
1729 must_be_writable(tst, "ioctl(CDROMREADTOCHDR)", arg3,
1730 sizeof(struct cdrom_tochdr));
1731 KERNEL_DO_SYSCALL(tid,res);
1732 if (!VG_(is_kerror)(res) && res == 0)
1733 make_readable (arg3, sizeof(struct cdrom_tochdr));
1734 break;
1735 case CDROMREADTOCENTRY:
1736 must_be_readable(tst, "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
1737 (int) &(((struct cdrom_tocentry *) arg3)->cdte_format),
1738 sizeof(((struct cdrom_tocentry *) arg3)->cdte_format));
1739 must_be_readable(tst, "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
1740 (int) &(((struct cdrom_tocentry *) arg3)->cdte_track),
1741 sizeof(((struct cdrom_tocentry *) arg3)->cdte_track));
1742 must_be_writable(tst, "ioctl(CDROMREADTOCENTRY)", arg3,
1743 sizeof(struct cdrom_tocentry));
1744 KERNEL_DO_SYSCALL(tid,res);
1745 if (!VG_(is_kerror)(res) && res == 0)
1746 make_readable (arg3, sizeof(struct cdrom_tochdr));
1747 break;
1748 case CDROMPLAYMSF:
1749 must_be_readable(tst, "ioctl(CDROMPLAYMSF)", arg3,
1750 sizeof(struct cdrom_msf));
1751 KERNEL_DO_SYSCALL(tid,res);
1752 break;
1753
sewardjde4a1d02002-03-22 01:27:54 +00001754 /* We don't have any specific information on it, so
1755 try to do something reasonable based on direction and
1756 size bits. The encoding scheme is described in
1757 /usr/include/asm/ioctl.h. */
1758 default: {
1759 UInt dir = _IOC_DIR(arg2);
1760 UInt size = _IOC_SIZE(arg2);
1761 if (/* size == 0 || */ dir == _IOC_NONE) {
1762 VG_(message)(Vg_UserMsg,
1763 "Warning: noted but unhandled ioctl 0x%x"
1764 " with no size/direction hints",
1765 arg2);
1766 VG_(message)(Vg_UserMsg,
1767 " This could cause spurious value errors"
1768 " to appear.");
1769 VG_(message)(Vg_UserMsg,
1770 " See README_MISSING_SYSCALL_OR_IOCTL for guidance on"
1771 " writing a proper wrapper." );
1772 } else {
1773 if ((dir & _IOC_READ) && size > 0)
sewardj8c824512002-04-14 04:16:48 +00001774 must_be_readable(tst, "ioctl(generic)", arg3, size);
sewardjde4a1d02002-03-22 01:27:54 +00001775 if ((dir & _IOC_WRITE) && size > 0)
sewardj8c824512002-04-14 04:16:48 +00001776 must_be_writable(tst, "ioctl(generic)", arg3, size);
sewardjde4a1d02002-03-22 01:27:54 +00001777 }
sewardj2e93c502002-04-12 11:12:52 +00001778 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001779 if (size > 0 && (dir & _IOC_WRITE)
1780 && !VG_(is_kerror)(res) && res == 0)
1781 make_readable (arg3, size);
1782 break;
1783 }
1784 }
1785 break;
1786
1787 case __NR_kill: /* syscall 37 */
1788 /* int kill(pid_t pid, int sig); */
1789 if (VG_(clo_trace_syscalls))
1790 VG_(printf)("kill ( %d, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00001791 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001792 break;
1793
1794 case __NR_link: /* syscall 9 */
1795 /* int link(const char *oldpath, const char *newpath); */
1796 if (VG_(clo_trace_syscalls))
1797 VG_(printf)("link ( %p, %p)\n", arg1, arg2);
sewardj8c824512002-04-14 04:16:48 +00001798 must_be_readable_asciiz( tst, "link(oldpath)", arg1);
1799 must_be_readable_asciiz( tst, "link(newpath)", arg2);
sewardj2e93c502002-04-12 11:12:52 +00001800 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001801 break;
1802
1803 case __NR_lseek: /* syscall 19 */
1804 /* off_t lseek(int fildes, off_t offset, int whence); */
1805 if (VG_(clo_trace_syscalls))
1806 VG_(printf)("lseek ( %d, %d, %d )\n",arg1,arg2,arg3);
sewardj2e93c502002-04-12 11:12:52 +00001807 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001808 break;
1809
1810 case __NR__llseek: /* syscall 140 */
1811 /* int _llseek(unsigned int fd, unsigned long offset_high,
1812 unsigned long offset_low,
1813 loff_t * result, unsigned int whence); */
1814 if (VG_(clo_trace_syscalls))
1815 VG_(printf)("llseek ( %d, 0x%x, 0x%x, %p, %d )\n",
1816 arg1,arg2,arg3,arg4,arg5);
sewardj8c824512002-04-14 04:16:48 +00001817 must_be_writable( tst, "llseek(result)", arg4, sizeof(loff_t));
sewardj2e93c502002-04-12 11:12:52 +00001818 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001819 if (!VG_(is_kerror)(res) && res == 0)
1820 make_readable( arg4, sizeof(loff_t) );
1821 break;
1822
1823 case __NR_lstat: /* syscall 107 */
1824 /* int lstat(const char *file_name, struct stat *buf); */
1825 if (VG_(clo_trace_syscalls))
1826 VG_(printf)("lstat ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001827 must_be_readable_asciiz( tst, "lstat(file_name)", arg1 );
1828 must_be_writable( tst, "lstat(buf)", arg2, sizeof(struct stat) );
sewardj2e93c502002-04-12 11:12:52 +00001829 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001830 if (!VG_(is_kerror)(res) && res == 0) {
1831 make_readable( arg2, sizeof(struct stat) );
1832 }
1833 break;
1834
1835# if defined(__NR_lstat64)
1836 case __NR_lstat64: /* syscall 196 */
1837 /* int lstat64(const char *file_name, struct stat64 *buf); */
1838 if (VG_(clo_trace_syscalls))
1839 VG_(printf)("lstat64 ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001840 must_be_readable_asciiz( tst, "lstat64(file_name)", arg1 );
1841 must_be_writable( tst, "lstat64(buf)", arg2, sizeof(struct stat64) );
sewardj2e93c502002-04-12 11:12:52 +00001842 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001843 if (!VG_(is_kerror)(res) && res == 0) {
1844 make_readable( arg2, sizeof(struct stat64) );
1845 }
1846 break;
1847# endif
1848
1849 case __NR_mkdir: /* syscall 39 */
1850 /* int mkdir(const char *pathname, mode_t mode); */
1851 if (VG_(clo_trace_syscalls))
1852 VG_(printf)("mkdir ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001853 must_be_readable_asciiz( tst, "mkdir(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00001854 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001855 break;
1856
1857# if defined(__NR_mmap2)
1858 case __NR_mmap2: /* syscall 192 */
1859 /* My impression is that this is exactly like __NR_mmap
1860 except that all 6 args are passed in regs, rather than in
1861 a memory-block. */
1862 /* void* mmap(void *start, size_t length, int prot,
1863 int flags, int fd, off_t offset);
1864 */
1865 {
sewardj2e93c502002-04-12 11:12:52 +00001866 UInt arg6 = tst->m_ebp;
sewardjde4a1d02002-03-22 01:27:54 +00001867 if (VG_(clo_trace_syscalls))
1868 VG_(printf)("mmap2 ( %p, %d, %d, %d, %d, %d )\n",
1869 arg1, arg2, arg3, arg4, arg5, arg6 );
sewardj2e93c502002-04-12 11:12:52 +00001870 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001871 /* !!! shouldn't we also be doing the symtab loading stuff as
1872 in __NR_mmap ? */
1873 if (!VG_(is_kerror)(res))
1874 approximate_mmap_permissions( (Addr)res, arg2, arg3 );
1875 }
1876 break;
1877# endif
1878
1879 case __NR_mmap: /* syscall 90 */
1880 /* void* mmap(void *start, size_t length, int prot,
1881 int flags, int fd, off_t offset);
1882 */
1883 {
1884 Bool arg_block_readable
1885 = VG_(clo_instrument)
1886 ? VGM_(check_readable)(arg1, 6*sizeof(UInt), NULL)
1887 : True;
sewardj8c824512002-04-14 04:16:48 +00001888 must_be_readable( tst, "mmap(args)", arg1, 6*sizeof(UInt) );
sewardjde4a1d02002-03-22 01:27:54 +00001889 if (arg_block_readable) {
1890 UInt* arg_block = (UInt*)arg1;
1891 UInt arg6;
1892 arg1 = arg_block[0];
1893 arg2 = arg_block[1];
1894 arg3 = arg_block[2];
1895 arg4 = arg_block[3];
1896 arg5 = arg_block[4];
1897 arg6 = arg_block[5];
1898 if (VG_(clo_trace_syscalls))
1899 VG_(printf)("mmap ( %p, %d, %d, %d, %d, %d )\n",
1900 arg1, arg2, arg3, arg4, arg5, arg6 );
1901 }
sewardj2e93c502002-04-12 11:12:52 +00001902 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001903 if (arg_block_readable && !VG_(is_kerror)(res))
1904 approximate_mmap_permissions( (Addr)res, arg2, arg3 );
1905 if (arg_block_readable && !VG_(is_kerror)(res)
1906 && (arg3 & PROT_EXEC)) {
1907 /* The client mmap'ed a segment with executable
1908 permissions. Tell the symbol-table loader, so that it
1909 has an opportunity to pick up more symbols if this mmap
1910 was caused by the client loading a new .so via
1911 dlopen(). This is important for debugging KDE. */
1912 VG_(read_symbols)();
1913 }
1914 }
1915
1916 break;
1917
1918 case __NR_mprotect: /* syscall 125 */
1919 /* int mprotect(const void *addr, size_t len, int prot); */
1920 /* should addr .. addr+len-1 be checked before the call? */
1921 if (VG_(clo_trace_syscalls))
1922 VG_(printf)("mprotect ( %p, %d, %d )\n", arg1,arg2,arg3);
sewardj2e93c502002-04-12 11:12:52 +00001923 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001924 if (!VG_(is_kerror)(res))
1925 approximate_mmap_permissions ( arg1, arg2, arg3 );
1926 break;
1927
1928 case __NR_munmap: /* syscall 91 */
1929 /* int munmap(void *start, size_t length); */
1930 /* should start .. start+length-1 be checked before the call? */
1931 if (VG_(clo_trace_syscalls))
1932 VG_(printf)("munmap ( %p, %d )\n", arg1,arg2);
sewardj2e93c502002-04-12 11:12:52 +00001933 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001934 if (!VG_(is_kerror)(res)) {
1935 /* Mash around start and length so that the area passed to
1936 make_noaccess() exactly covers an integral number of
1937 pages. If we don't do that, our idea of addressible
1938 memory diverges from that of the kernel's, which causes
1939 the leak detector to crash. */
1940 Addr start = arg1;
1941 Addr length = arg2;
1942 while ((start % VKI_BYTES_PER_PAGE) > 0) { start--; length++; }
1943 while (((start+length) % VKI_BYTES_PER_PAGE) > 0) { length++; }
1944 /*
1945 VG_(printf)("MUNMAP: correct (%p for %d) to (%p for %d) %s\n",
1946 arg1, arg2, start, length, (arg1!=start || arg2!=length)
1947 ? "CHANGE" : "");
1948 */
1949 make_noaccess( start, length );
1950 /* Tell our symbol table machinery about this, so that if
1951 this happens to be a .so being unloaded, the relevant
1952 symbols are removed too. */
1953 VG_(symtab_notify_munmap) ( start, length );
1954 }
1955 break;
1956
1957 case __NR_nanosleep: /* syscall 162 */
1958 /* int nanosleep(const struct timespec *req, struct timespec *rem); */
1959 if (VG_(clo_trace_syscalls))
1960 VG_(printf)("nanosleep ( %p, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00001961 must_be_readable ( tst, "nanosleep(req)", arg1,
sewardjde4a1d02002-03-22 01:27:54 +00001962 sizeof(struct timespec) );
1963 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00001964 must_be_writable ( tst, "nanosleep(rem)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00001965 sizeof(struct timespec) );
sewardj2e93c502002-04-12 11:12:52 +00001966 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001967 /* Somewhat bogus ... is only written by the kernel if
1968 res == -1 && errno == EINTR. */
1969 if (!VG_(is_kerror)(res) && arg2 != (UInt)NULL)
1970 make_readable ( arg2, sizeof(struct timespec) );
1971 break;
1972
1973 case __NR__newselect: /* syscall 142 */
1974 /* int select(int n,
1975 fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
1976 struct timeval *timeout);
1977 */
1978 if (VG_(clo_trace_syscalls))
1979 VG_(printf)("newselect ( %d, %p, %p, %p, %p )\n",
1980 arg1,arg2,arg3,arg4,arg5);
1981 if (arg2 != 0)
sewardj8c824512002-04-14 04:16:48 +00001982 must_be_readable( tst, "newselect(readfds)",
sewardjde4a1d02002-03-22 01:27:54 +00001983 arg2, arg1/8 /* __FD_SETSIZE/8 */ );
1984 if (arg3 != 0)
sewardj8c824512002-04-14 04:16:48 +00001985 must_be_readable( tst, "newselect(writefds)",
sewardjde4a1d02002-03-22 01:27:54 +00001986 arg3, arg1/8 /* __FD_SETSIZE/8 */ );
1987 if (arg4 != 0)
sewardj8c824512002-04-14 04:16:48 +00001988 must_be_readable( tst, "newselect(exceptfds)",
sewardjde4a1d02002-03-22 01:27:54 +00001989 arg4, arg1/8 /* __FD_SETSIZE/8 */ );
1990 if (arg5 != 0)
sewardj8c824512002-04-14 04:16:48 +00001991 must_be_readable( tst, "newselect(timeout)", arg5,
sewardjde4a1d02002-03-22 01:27:54 +00001992 sizeof(struct timeval) );
sewardj2e93c502002-04-12 11:12:52 +00001993 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00001994 break;
1995
1996 case __NR_open: /* syscall 5 */
1997 /* int open(const char *pathname, int flags); */
1998 if (VG_(clo_trace_syscalls))
1999 VG_(printf)("open ( %p(%s), %d ) --> ",arg1,arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002000 must_be_readable_asciiz( tst, "open(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002001 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002002 if (VG_(clo_trace_syscalls))
2003 VG_(printf)("%d\n",res);
2004 break;
2005
2006 case __NR_pipe: /* syscall 42 */
2007 /* int pipe(int filedes[2]); */
2008 if (VG_(clo_trace_syscalls))
2009 VG_(printf)("pipe ( %p ) ...\n", arg1);
sewardj8c824512002-04-14 04:16:48 +00002010 must_be_writable( tst, "pipe(filedes)", arg1, 2*sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00002011 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002012 if (!VG_(is_kerror)(res))
2013 make_readable ( arg1, 2*sizeof(int) );
2014 if (VG_(clo_trace_syscalls) && !VG_(is_kerror)(res))
sewardj2e93c502002-04-12 11:12:52 +00002015 VG_(printf)("SYSCALL[%d] pipe --> (rd %d, wr %d)\n",
2016 VG_(getpid)(),
sewardjde4a1d02002-03-22 01:27:54 +00002017 ((UInt*)arg1)[0], ((UInt*)arg1)[1] );
2018 break;
2019
2020 case __NR_poll: /* syscall 168 */
2021 /* struct pollfd {
2022 int fd; -- file descriptor
2023 short events; -- requested events
2024 short revents; -- returned events
2025 };
2026 int poll(struct pollfd *ufds, unsigned int nfds,
2027 int timeout)
2028 */
2029 if (VG_(clo_trace_syscalls))
2030 VG_(printf)("poll ( %d, %d, %d )\n",arg1,arg2,arg3);
2031 /* In fact some parts of this struct should be readable too.
2032 This should be fixed properly. */
sewardj8c824512002-04-14 04:16:48 +00002033 must_be_writable( tst, "poll(ufds)",
2034 arg1, arg2 * sizeof(struct pollfd) );
sewardj2e93c502002-04-12 11:12:52 +00002035 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002036 if (!VG_(is_kerror)(res) && res > 0) {
2037 Int i;
2038 struct pollfd * arr = (struct pollfd *)arg1;
2039 for (i = 0; i < arg2; i++)
2040 make_readable( (Addr)(&arr[i].revents), sizeof(Short) );
2041 }
2042 break;
2043
sewardjde4a1d02002-03-22 01:27:54 +00002044 case __NR_readlink: /* syscall 85 */
2045 /* int readlink(const char *path, char *buf, size_t bufsiz); */
2046 if (VG_(clo_trace_syscalls))
2047 VG_(printf)("readlink ( %p, %p, %d )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002048 must_be_readable_asciiz( tst, "readlink(path)", arg1 );
2049 must_be_writable ( tst, "readlink(buf)", arg2,arg3 );
sewardj2e93c502002-04-12 11:12:52 +00002050 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002051 if (!VG_(is_kerror)(res) && res > 0) {
2052 make_readable ( arg2, res );
2053 }
2054 break;
2055
2056 case __NR_readv: { /* syscall 145 */
2057 /* int readv(int fd, const struct iovec * vector, size_t count); */
2058 UInt i;
2059 struct iovec * vec;
2060 if (VG_(clo_trace_syscalls))
2061 VG_(printf)("readv ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002062 must_be_readable( tst, "readv(vector)",
sewardjde4a1d02002-03-22 01:27:54 +00002063 arg2, arg3 * sizeof(struct iovec) );
2064 /* ToDo: don't do any of the following if the vector is invalid */
2065 vec = (struct iovec *)arg2;
2066 for (i = 0; i < arg3; i++)
sewardj8c824512002-04-14 04:16:48 +00002067 must_be_writable( tst, "readv(vector[...])",
sewardjde4a1d02002-03-22 01:27:54 +00002068 (UInt)vec[i].iov_base,vec[i].iov_len );
sewardj2e93c502002-04-12 11:12:52 +00002069 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002070 if (!VG_(is_kerror)(res) && res > 0) {
2071 /* res holds the number of bytes read. */
2072 for (i = 0; i < arg3; i++) {
2073 Int nReadThisBuf = vec[i].iov_len;
2074 if (nReadThisBuf > res) nReadThisBuf = res;
2075 make_readable( (UInt)vec[i].iov_base, nReadThisBuf );
2076 res -= nReadThisBuf;
2077 if (res < 0) VG_(panic)("vg_wrap_syscall: readv: res < 0");
2078 }
2079 }
2080 break;
2081 }
2082
2083 case __NR_rename: /* syscall 38 */
2084 /* int rename(const char *oldpath, const char *newpath); */
2085 if (VG_(clo_trace_syscalls))
2086 VG_(printf)("rename ( %p, %p )\n", arg1, arg2 );
sewardj8c824512002-04-14 04:16:48 +00002087 must_be_readable_asciiz( tst, "rename(oldpath)", arg1 );
2088 must_be_readable_asciiz( tst, "rename(newpath)", arg2 );
sewardj2e93c502002-04-12 11:12:52 +00002089 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002090 break;
2091
2092 case __NR_rmdir: /* syscall 40 */
2093 /* int rmdir(const char *pathname); */
2094 if (VG_(clo_trace_syscalls))
2095 VG_(printf)("rmdir ( %p )\n", arg1);
sewardj8c824512002-04-14 04:16:48 +00002096 must_be_readable_asciiz( tst, "rmdir(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002097 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002098 break;
2099
2100 case __NR_sched_setparam:
2101 case __NR_sched_getparam:
2102 case __NR_sched_yield:
sewardjde4a1d02002-03-22 01:27:54 +00002103 if (VG_(clo_instrument)) {
2104 VG_(message)(Vg_UserMsg,
2105 "Warning: noted but unhandled __NR_sched_* syscall (%d).",
2106 syscallno);
2107 VG_(message)(Vg_UserMsg,
2108 " This could cause spurious value errors"
2109 " to appear.");
2110 }
sewardj2e93c502002-04-12 11:12:52 +00002111 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002112 break;
2113
2114 case __NR_select: /* syscall 82 */
2115 /* struct sel_arg_struct {
2116 unsigned long n;
2117 fd_set *inp, *outp, *exp;
2118 struct timeval *tvp;
2119 };
2120 int old_select(struct sel_arg_struct *arg);
2121 */
2122 {
2123 Bool arg_block_readable
2124 = VG_(clo_instrument)
2125 ? VGM_(check_readable)(arg1, 5*sizeof(UInt), NULL)
2126 : True;
sewardj8c824512002-04-14 04:16:48 +00002127 must_be_readable ( tst, "select(args)", arg1, 5*sizeof(UInt) );
sewardjde4a1d02002-03-22 01:27:54 +00002128 if (arg_block_readable) {
2129 UInt* arg_struct = (UInt*)arg1;
2130 arg1 = arg_struct[0];
2131 arg2 = arg_struct[1];
2132 arg3 = arg_struct[2];
2133 arg4 = arg_struct[3];
2134 arg5 = arg_struct[4];
2135
2136 if (VG_(clo_trace_syscalls))
2137 VG_(printf)("select ( %d, %p, %p, %p, %p )\n",
2138 arg1,arg2,arg3,arg4,arg5);
2139 if (arg2 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002140 must_be_readable(tst, "select(readfds)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002141 arg1/8 /* __FD_SETSIZE/8 */ );
2142 if (arg3 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002143 must_be_readable(tst, "select(writefds)", arg3,
sewardjde4a1d02002-03-22 01:27:54 +00002144 arg1/8 /* __FD_SETSIZE/8 */ );
2145 if (arg4 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002146 must_be_readable(tst, "select(exceptfds)", arg4,
sewardjde4a1d02002-03-22 01:27:54 +00002147 arg1/8 /* __FD_SETSIZE/8 */ );
2148 if (arg5 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002149 must_be_readable(tst, "select(timeout)", arg5,
sewardjde4a1d02002-03-22 01:27:54 +00002150 sizeof(struct timeval) );
2151 }
2152 }
sewardj2e93c502002-04-12 11:12:52 +00002153 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002154 break;
2155
2156 case __NR_setitimer: /* syscall 104 */
2157 /* setitimer(int which, const struct itimerval *value,
2158 struct itimerval *ovalue); */
2159 if (VG_(clo_trace_syscalls))
2160 VG_(printf)("setitimer ( %d, %p, %p )\n", arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002161 must_be_readable(tst, "setitimer(value)",
sewardjde4a1d02002-03-22 01:27:54 +00002162 arg2, sizeof(struct itimerval) );
2163 if (arg3 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002164 must_be_writable(tst, "setitimer(ovalue)",
sewardjde4a1d02002-03-22 01:27:54 +00002165 arg3, sizeof(struct itimerval));
sewardj2e93c502002-04-12 11:12:52 +00002166 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002167 if (!VG_(is_kerror)(res) && arg3 != (Addr)NULL) {
2168 make_readable(arg3, sizeof(struct itimerval));
2169 }
2170 break;
2171
2172# if defined(__NR_setfsgid32)
2173 case __NR_setfsgid32: /* syscall 216 */
2174 /* int setfsgid(uid_t fsgid); */
2175 if (VG_(clo_trace_syscalls))
2176 VG_(printf)("setfsgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002177 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002178 break;
2179# endif
2180
2181# if defined(__NR_setgid32)
2182 case __NR_setgid32: /* syscall 214 */
2183# endif
2184 case __NR_setgid: /* syscall 46 */
2185 /* int setgid(gid_t gid); */
2186 if (VG_(clo_trace_syscalls))
2187 VG_(printf)("setgid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002188 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002189 break;
2190
2191 case __NR_setsid: /* syscall 66 */
2192 /* pid_t setsid(void); */
2193 if (VG_(clo_trace_syscalls))
2194 VG_(printf)("setsid ()\n");
sewardj2e93c502002-04-12 11:12:52 +00002195 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002196 break;
2197
2198# if defined(__NR_setgroups32)
2199 case __NR_setgroups32: /* syscall 206 */
sewardj2f0de322002-03-24 10:17:25 +00002200# endif
2201 case __NR_setgroups: /* syscall 81 */
sewardjde4a1d02002-03-22 01:27:54 +00002202 /* int setgroups(size_t size, const gid_t *list); */
2203 if (VG_(clo_trace_syscalls))
2204 VG_(printf)("setgroups ( %d, %p )\n", arg1, arg2);
2205 if (arg1 > 0)
sewardj8c824512002-04-14 04:16:48 +00002206 must_be_readable ( tst, "setgroups(list)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002207 arg1 * sizeof(gid_t) );
sewardj2e93c502002-04-12 11:12:52 +00002208 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002209 break;
sewardjde4a1d02002-03-22 01:27:54 +00002210
2211 case __NR_setpgid: /* syscall 57 */
2212 /* int setpgid(pid_t pid, pid_t pgid); */
2213 if (VG_(clo_trace_syscalls))
2214 VG_(printf)("setpgid ( %d, %d )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +00002215 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002216 break;
2217
2218# if defined(__NR_setregid32)
2219 case __NR_setregid32: /* syscall 204 */
2220 /* int setregid(gid_t rgid, gid_t egid); */
2221 if (VG_(clo_trace_syscalls))
2222 VG_(printf)("setregid32(?) ( %d, %d )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +00002223 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002224 break;
2225# endif
2226
2227# if defined(__NR_setresuid32)
2228 case __NR_setresuid32: /* syscall 208 */
2229 /* int setresuid(uid_t ruid, uid_t euid, uid_t suid); */
2230 if (VG_(clo_trace_syscalls))
2231 VG_(printf)("setresuid32(?) ( %d, %d, %d )\n", arg1, arg2, arg3);
sewardj2e93c502002-04-12 11:12:52 +00002232 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002233 break;
2234# endif
2235
2236# if defined(__NR_setreuid32)
2237 case __NR_setreuid32: /* syscall 203 */
2238# endif
2239 case __NR_setreuid: /* syscall 70 */
2240 /* int setreuid(uid_t ruid, uid_t euid); */
2241 if (VG_(clo_trace_syscalls))
2242 VG_(printf)("setreuid ( 0x%x, 0x%x )\n", arg1, arg2);
sewardj2e93c502002-04-12 11:12:52 +00002243 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002244 break;
2245
2246 case __NR_setrlimit: /* syscall 75 */
2247 /* int setrlimit (int resource, const struct rlimit *rlim); */
2248 if (VG_(clo_trace_syscalls))
2249 VG_(printf)("setrlimit ( %d, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002250 must_be_readable( tst, "setrlimit(rlim)", arg2, sizeof(struct rlimit) );
sewardj2e93c502002-04-12 11:12:52 +00002251 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002252 break;
2253
2254# if defined(__NR_setuid32)
2255 case __NR_setuid32: /* syscall 213 */
2256# endif
2257 case __NR_setuid: /* syscall 23 */
2258 /* int setuid(uid_t uid); */
2259 if (VG_(clo_trace_syscalls))
2260 VG_(printf)("setuid ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002261 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002262 break;
2263
2264 case __NR_socketcall: /* syscall 102 */
2265 /* int socketcall(int call, unsigned long *args); */
2266 if (VG_(clo_trace_syscalls))
2267 VG_(printf)("socketcall ( %d, %p )\n",arg1,arg2);
2268 switch (arg1 /* request */) {
2269
2270 case SYS_SOCKETPAIR:
2271 /* int socketpair(int d, int type, int protocol, int sv[2]); */
sewardj8c824512002-04-14 04:16:48 +00002272 must_be_readable( tst, "socketcall.socketpair(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002273 arg2, 4*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002274 must_be_writable( tst, "socketcall.socketpair(sv)",
sewardjde4a1d02002-03-22 01:27:54 +00002275 ((UInt*)arg2)[3], 2*sizeof(int) );
sewardj2e93c502002-04-12 11:12:52 +00002276 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002277 if (!VG_(is_kerror)(res))
2278 make_readable ( ((UInt*)arg2)[3], 2*sizeof(int) );
2279 break;
2280
2281 case SYS_SOCKET:
2282 /* int socket(int domain, int type, int protocol); */
sewardj8c824512002-04-14 04:16:48 +00002283 must_be_readable( tst, "socketcall.socket(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002284 arg2, 3*sizeof(Addr) );
sewardj2e93c502002-04-12 11:12:52 +00002285 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002286 break;
2287
2288 case SYS_BIND:
2289 /* int bind(int sockfd, struct sockaddr *my_addr,
2290 int addrlen); */
sewardj8c824512002-04-14 04:16:48 +00002291 must_be_readable( tst, "socketcall.bind(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002292 arg2, 3*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002293 must_be_readable( tst, "socketcall.bind(my_addr)",
sewardjde4a1d02002-03-22 01:27:54 +00002294 ((UInt*)arg2)[1], ((UInt*)arg2)[2] );
sewardj2e93c502002-04-12 11:12:52 +00002295 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002296 break;
2297
2298 case SYS_LISTEN:
2299 /* int listen(int s, int backlog); */
sewardj8c824512002-04-14 04:16:48 +00002300 must_be_readable( tst, "socketcall.listen(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002301 arg2, 2*sizeof(Addr) );
sewardj2e93c502002-04-12 11:12:52 +00002302 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002303 break;
2304
2305 case SYS_ACCEPT: {
2306 /* int accept(int s, struct sockaddr *addr, int *p_addrlen); */
2307 Addr addr;
2308 Addr p_addrlen;
2309 UInt addrlen_in, addrlen_out;
sewardj8c824512002-04-14 04:16:48 +00002310 must_be_readable( tst, "socketcall.accept(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002311 arg2, 3*sizeof(Addr) );
2312 addr = ((UInt*)arg2)[1];
2313 p_addrlen = ((UInt*)arg2)[2];
2314 if (p_addrlen != (Addr)NULL) {
sewardj8c824512002-04-14 04:16:48 +00002315 must_be_readable ( tst, "socketcall.accept(addrlen)",
sewardjde4a1d02002-03-22 01:27:54 +00002316 p_addrlen, sizeof(int) );
2317 addrlen_in = safe_dereference( p_addrlen, 0 );
sewardj8c824512002-04-14 04:16:48 +00002318 must_be_writable ( tst, "socketcall.accept(addr)",
sewardjde4a1d02002-03-22 01:27:54 +00002319 addr, addrlen_in );
2320 }
sewardj2e93c502002-04-12 11:12:52 +00002321 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002322 if (!VG_(is_kerror)(res) && res >= 0 && p_addrlen != (Addr)NULL) {
2323 addrlen_out = safe_dereference( p_addrlen, 0 );
2324 if (addrlen_out > 0)
2325 make_readable( addr, addrlen_out );
2326 }
2327 break;
2328 }
2329
2330 case SYS_SENDTO:
2331 /* int sendto(int s, const void *msg, int len,
2332 unsigned int flags,
2333 const struct sockaddr *to, int tolen); */
sewardj8c824512002-04-14 04:16:48 +00002334 must_be_readable( tst, "socketcall.sendto(args)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002335 6*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002336 must_be_readable( tst, "socketcall.sendto(msg)",
sewardjde4a1d02002-03-22 01:27:54 +00002337 ((UInt*)arg2)[1], /* msg */
2338 ((UInt*)arg2)[2] /* len */ );
sewardj8c824512002-04-14 04:16:48 +00002339 must_be_readable( tst, "socketcall.sendto(to)",
sewardjde4a1d02002-03-22 01:27:54 +00002340 ((UInt*)arg2)[4], /* to */
2341 ((UInt*)arg2)[5] /* tolen */ );
sewardj2e93c502002-04-12 11:12:52 +00002342 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002343 break;
2344
2345 case SYS_SEND:
2346 /* int send(int s, const void *msg, size_t len, int flags); */
sewardj8c824512002-04-14 04:16:48 +00002347 must_be_readable( tst, "socketcall.send(args)", arg2,
sewardjde4a1d02002-03-22 01:27:54 +00002348 4*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002349 must_be_readable( tst, "socketcall.send(msg)",
sewardjde4a1d02002-03-22 01:27:54 +00002350 ((UInt*)arg2)[1], /* msg */
2351 ((UInt*)arg2)[2] /* len */ );
sewardj2e93c502002-04-12 11:12:52 +00002352 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002353 break;
2354
2355 case SYS_RECVFROM:
2356 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
2357 struct sockaddr *from, int *fromlen); */
sewardj8c824512002-04-14 04:16:48 +00002358 must_be_readable( tst, "socketcall.recvfrom(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002359 arg2, 6*sizeof(Addr) );
2360 if ( ((UInt*)arg2)[4] /* from */ != 0) {
sewardj8c824512002-04-14 04:16:48 +00002361 must_be_readable( tst, "socketcall.recvfrom(fromlen)",
sewardjde4a1d02002-03-22 01:27:54 +00002362 ((UInt*)arg2)[5] /* fromlen */,
2363 sizeof(int) );
sewardj8c824512002-04-14 04:16:48 +00002364 must_be_writable( tst, "socketcall.recvfrom(from)",
sewardjde4a1d02002-03-22 01:27:54 +00002365 ((UInt*)arg2)[4], /*from*/
2366 safe_dereference( (Addr)
2367 ((UInt*)arg2)[5], 0 ) );
2368 }
sewardj8c824512002-04-14 04:16:48 +00002369 must_be_writable( tst, "socketcall.recvfrom(buf)",
sewardjde4a1d02002-03-22 01:27:54 +00002370 ((UInt*)arg2)[1], /* buf */
2371 ((UInt*)arg2)[2] /* len */ );
sewardj2e93c502002-04-12 11:12:52 +00002372 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002373 if (!VG_(is_kerror)(res) && res >= 0) {
2374 make_readable( ((UInt*)arg2)[1], /* buf */
2375 ((UInt*)arg2)[2] /* len */ );
2376 if ( ((UInt*)arg2)[4] /* from */ != 0) {
2377 make_readable(
2378 ((UInt*)arg2)[4], /*from*/
2379 safe_dereference( (Addr) ((UInt*)arg2)[5], 0 ) );
2380 }
2381 }
2382 /* phew! */
2383 break;
2384
2385 case SYS_RECV:
2386 /* int recv(int s, void *buf, int len, unsigned int flags); */
2387 /* man 2 recv says:
2388 The recv call is normally used only on a connected socket
2389 (see connect(2)) and is identical to recvfrom with a NULL
2390 from parameter.
2391 */
sewardj8c824512002-04-14 04:16:48 +00002392 must_be_readable( tst, "socketcall.recv(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002393 arg2, 4*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002394 must_be_writable( tst, "socketcall.recv(buf)",
sewardjde4a1d02002-03-22 01:27:54 +00002395 ((UInt*)arg2)[1], /* buf */
2396 ((UInt*)arg2)[2] /* len */ );
sewardj2e93c502002-04-12 11:12:52 +00002397 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002398 if (!VG_(is_kerror)(res) && res >= 0
2399 && ((UInt*)arg2)[1] != (UInt)NULL) {
2400 make_readable( ((UInt*)arg2)[1], /* buf */
2401 ((UInt*)arg2)[2] /* len */ );
2402 }
2403 break;
2404
2405 case SYS_CONNECT: {
2406 struct sockaddr *sa;
2407 /* int connect(int sockfd,
2408 struct sockaddr *serv_addr, int addrlen ); */
sewardj8c824512002-04-14 04:16:48 +00002409 must_be_readable( tst, "socketcall.connect(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002410 arg2, 3*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002411 must_be_readable( tst, "socketcall.connect(serv_addr.sa_family)",
sewardjde4a1d02002-03-22 01:27:54 +00002412 ((UInt*)arg2)[1], /* serv_addr */
2413 sizeof (sa_family_t));
2414 sa = (struct sockaddr *) (((UInt*)arg2)[1]);
2415 if (sa->sa_family == AF_UNIX)
sewardj8c824512002-04-14 04:16:48 +00002416 must_be_readable_asciiz( tst,
sewardjde4a1d02002-03-22 01:27:54 +00002417 "socketcall.connect(serv_addr.sun_path)",
2418 (UInt) ((struct sockaddr_un *) sa)->sun_path);
2419 /* XXX There probably should be more cases here since not
2420 all of the struct sockaddr_XXX must be initialized. But
2421 wait until something pops up. */
2422 else
sewardj8c824512002-04-14 04:16:48 +00002423 must_be_readable( tst, "socketcall.connect(serv_addr)",
sewardjde4a1d02002-03-22 01:27:54 +00002424 ((UInt*)arg2)[1], /* serv_addr */
2425 ((UInt*)arg2)[2] /* addrlen */ );
sewardj2e93c502002-04-12 11:12:52 +00002426 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002427 break;
2428 }
2429
2430 case SYS_SETSOCKOPT:
2431 /* int setsockopt(int s, int level, int optname,
2432 const void *optval, int optlen); */
sewardj8c824512002-04-14 04:16:48 +00002433 must_be_readable( tst, "socketcall.setsockopt(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002434 arg2, 5*sizeof(Addr) );
sewardj8c824512002-04-14 04:16:48 +00002435 must_be_readable( tst, "socketcall.setsockopt(optval)",
sewardjde4a1d02002-03-22 01:27:54 +00002436 ((UInt*)arg2)[3], /* optval */
2437 ((UInt*)arg2)[4] /* optlen */ );
sewardj2e93c502002-04-12 11:12:52 +00002438 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002439 break;
2440
2441 case SYS_GETSOCKOPT:
2442 /* int setsockopt(int s, int level, int optname,
2443 void *optval, socklen_t *optlen); */
sewardj8c824512002-04-14 04:16:48 +00002444 must_be_readable( tst, "socketcall.getsockopt(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002445 arg2, 5*sizeof(Addr) );
2446 {
2447 Addr optval_p = ((UInt*)arg2)[3];
2448 Addr optlen_p = ((UInt*)arg2)[4];
sewardj8c824512002-04-14 04:16:48 +00002449 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
sewardjde4a1d02002-03-22 01:27:54 +00002450 UInt optlen_after;
2451 UInt optlen = safe_dereference ( optlen_p, 0 );
2452 if (optlen > 0)
sewardj8c824512002-04-14 04:16:48 +00002453 must_be_writable( tst, "socketcall.getsockopt(optval)",
sewardjde4a1d02002-03-22 01:27:54 +00002454 optval_p, optlen );
sewardj2e93c502002-04-12 11:12:52 +00002455 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002456 optlen_after = safe_dereference ( optlen_p, 0 );
2457 if (!VG_(is_kerror)(res) && optlen > 0 && optlen_after > 0)
2458 make_readable( optval_p, optlen_after );
2459 }
2460 break;
2461
2462 case SYS_GETSOCKNAME:
2463 /* int getsockname(int s, struct sockaddr* name,
2464 int* namelen) */
sewardj8c824512002-04-14 04:16:48 +00002465 must_be_readable( tst, "socketcall.getsockname(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002466 arg2, 3*sizeof(Addr) );
2467 {
2468 UInt namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2469 if (namelen > 0)
sewardj8c824512002-04-14 04:16:48 +00002470 must_be_writable( tst, "socketcall.getsockname(name)",
sewardjde4a1d02002-03-22 01:27:54 +00002471 ((UInt*)arg2)[1], namelen );
sewardj2e93c502002-04-12 11:12:52 +00002472 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002473 if (!VG_(is_kerror)(res)) {
2474 namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2475 if (namelen > 0
2476 && ((UInt*)arg2)[1] != (UInt)NULL)
2477 make_readable( ((UInt*)arg2)[1], namelen );
2478 }
2479 }
2480 break;
2481
2482 case SYS_GETPEERNAME:
2483 /* int getpeername(int s, struct sockaddr* name,
2484 int* namelen) */
sewardj8c824512002-04-14 04:16:48 +00002485 must_be_readable( tst, "socketcall.getpeername(args)",
sewardjde4a1d02002-03-22 01:27:54 +00002486 arg2, 3*sizeof(Addr) );
2487 {
2488 UInt namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2489 if (namelen > 0)
sewardj8c824512002-04-14 04:16:48 +00002490 must_be_writable( tst, "socketcall.getpeername(name)",
sewardjde4a1d02002-03-22 01:27:54 +00002491 ((UInt*)arg2)[1], namelen );
sewardj2e93c502002-04-12 11:12:52 +00002492 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002493 if (!VG_(is_kerror)(res)) {
2494 namelen = safe_dereference( (Addr) ((UInt*)arg2)[2], 0);
2495 if (namelen > 0
2496 && ((UInt*)arg2)[1] != (UInt)NULL)
2497 make_readable( ((UInt*)arg2)[1], namelen );
2498 }
2499 }
2500 break;
2501
2502 case SYS_SHUTDOWN:
2503 /* int shutdown(int s, int how); */
sewardj8c824512002-04-14 04:16:48 +00002504 must_be_readable( tst, "socketcall.shutdown(args)",
2505 arg2, 2*sizeof(Addr) );
sewardj2e93c502002-04-12 11:12:52 +00002506 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002507 break;
2508
2509 case SYS_SENDMSG:
2510 {
2511 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
2512
2513 /* this causes warnings, and I don't get why. glibc bug?
2514 * (after all it's glibc providing the arguments array)
2515 must_be_readable( "socketcall.sendmsg(args)",
2516 arg2, 3*sizeof(Addr) );
2517 */
2518
2519 struct msghdr *msg = (struct msghdr *)((UInt *)arg2)[ 1 ];
sewardj8c824512002-04-14 04:16:48 +00002520 msghdr_foreachfield ( tst, msg, must_be_readable_sendmsg );
sewardjde4a1d02002-03-22 01:27:54 +00002521
sewardj2e93c502002-04-12 11:12:52 +00002522 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002523 break;
2524 }
2525
2526 case SYS_RECVMSG:
2527 {
2528 /* int recvmsg(int s, struct msghdr *msg, int flags); */
2529
2530 /* this causes warnings, and I don't get why. glibc bug?
2531 * (after all it's glibc providing the arguments array)
2532 must_be_readable( "socketcall.recvmsg(args)",
2533 arg2, 3*sizeof(Addr) );
2534 */
2535
2536 struct msghdr *msg = (struct msghdr *)((UInt *)arg2)[ 1 ];
sewardj8c824512002-04-14 04:16:48 +00002537 msghdr_foreachfield ( tst, msg, must_be_writable_recvmsg );
sewardjde4a1d02002-03-22 01:27:54 +00002538
sewardj2e93c502002-04-12 11:12:52 +00002539 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002540
2541 if ( !VG_(is_kerror)( res ) )
sewardj8c824512002-04-14 04:16:48 +00002542 msghdr_foreachfield( tst, msg, make_readable_recvmsg );
sewardjde4a1d02002-03-22 01:27:54 +00002543
2544 break;
2545 }
2546
2547 default:
2548 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",arg1);
2549 VG_(panic)("... bye!\n");
2550 break; /*NOTREACHED*/
2551 }
2552 break;
2553
2554 case __NR_stat: /* syscall 106 */
2555 /* int stat(const char *file_name, struct stat *buf); */
2556 if (VG_(clo_trace_syscalls))
2557 VG_(printf)("stat ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002558 must_be_readable_asciiz( tst, "stat(file_name)", arg1 );
2559 must_be_writable( tst, "stat(buf)", arg2, sizeof(struct stat) );
sewardj2e93c502002-04-12 11:12:52 +00002560 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002561 if (!VG_(is_kerror)(res))
2562 make_readable( arg2, sizeof(struct stat) );
2563 break;
2564
2565 case __NR_statfs: /* syscall 99 */
2566 /* int statfs(const char *path, struct statfs *buf); */
2567 if (VG_(clo_trace_syscalls))
2568 VG_(printf)("statfs ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002569 must_be_readable_asciiz( tst, "statfs(path)", arg1 );
2570 must_be_writable( tst, "stat(buf)", arg2, sizeof(struct statfs) );
sewardj2e93c502002-04-12 11:12:52 +00002571 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002572 if (!VG_(is_kerror)(res))
2573 make_readable( arg2, sizeof(struct statfs) );
2574 break;
2575
2576 case __NR_symlink: /* syscall 83 */
2577 /* int symlink(const char *oldpath, const char *newpath); */
2578 if (VG_(clo_trace_syscalls))
2579 VG_(printf)("symlink ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002580 must_be_readable_asciiz( tst, "symlink(oldpath)", arg1 );
2581 must_be_readable_asciiz( tst, "symlink(newpath)", arg2 );
sewardj2e93c502002-04-12 11:12:52 +00002582 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002583 break;
2584
2585# if defined(__NR_stat64)
2586 case __NR_stat64: /* syscall 195 */
2587 /* int stat64(const char *file_name, struct stat64 *buf); */
2588 if (VG_(clo_trace_syscalls))
2589 VG_(printf)("stat64 ( %p, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002590 must_be_readable_asciiz( tst, "stat64(file_name)", arg1 );
2591 must_be_writable( tst, "stat64(buf)", arg2, sizeof(struct stat64) );
sewardj2e93c502002-04-12 11:12:52 +00002592 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002593 if (!VG_(is_kerror)(res))
2594 make_readable( arg2, sizeof(struct stat64) );
2595 break;
2596# endif
2597
2598# if defined(__NR_fstat64)
2599 case __NR_fstat64: /* syscall 197 */
2600 /* int fstat64(int filedes, struct stat64 *buf); */
2601 if (VG_(clo_trace_syscalls))
2602 VG_(printf)("fstat64 ( %d, %p )\n",arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002603 must_be_writable( tst, "fstat64(buf)", arg2, sizeof(struct stat64) );
sewardj2e93c502002-04-12 11:12:52 +00002604 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002605 if (!VG_(is_kerror)(res))
2606 make_readable( arg2, sizeof(struct stat64) );
2607 break;
2608# endif
2609
2610 case __NR_sysinfo: /* syscall 116 */
2611 /* int sysinfo(struct sysinfo *info); */
2612 if (VG_(clo_trace_syscalls))
2613 VG_(printf)("sysinfo ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002614 must_be_writable( tst, "sysinfo(info)", arg1, sizeof(struct sysinfo) );
sewardj2e93c502002-04-12 11:12:52 +00002615 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002616 if (!VG_(is_kerror)(res))
2617 make_readable( arg1, sizeof(struct sysinfo) );
2618 break;
2619
2620 case __NR_time: /* syscall 13 */
2621 /* time_t time(time_t *t); */
2622 if (VG_(clo_trace_syscalls))
2623 VG_(printf)("time ( %p )\n",arg1);
2624 if (arg1 != (UInt)NULL) {
sewardj8c824512002-04-14 04:16:48 +00002625 must_be_writable( tst, "time", arg1, sizeof(time_t) );
sewardjde4a1d02002-03-22 01:27:54 +00002626 }
sewardj2e93c502002-04-12 11:12:52 +00002627 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002628 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
2629 make_readable( arg1, sizeof(time_t) );
2630 }
2631 break;
2632
2633 case __NR_times: /* syscall 43 */
2634 /* clock_t times(struct tms *buf); */
2635 if (VG_(clo_trace_syscalls))
2636 VG_(printf)("times ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002637 must_be_writable( tst, "times(buf)", arg1, sizeof(struct tms) );
sewardj2e93c502002-04-12 11:12:52 +00002638 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002639 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
2640 make_readable( arg1, sizeof(struct tms) );
2641 }
2642 break;
2643
2644 case __NR_truncate: /* syscall 92 */
2645 /* int truncate(const char *path, size_t length); */
2646 if (VG_(clo_trace_syscalls))
2647 VG_(printf)("truncate ( %p, %d )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002648 must_be_readable_asciiz( tst, "truncate(path)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002649 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002650 break;
2651
2652 case __NR_umask: /* syscall 60 */
2653 /* mode_t umask(mode_t mask); */
2654 if (VG_(clo_trace_syscalls))
2655 VG_(printf)("umask ( %d )\n", arg1);
sewardj2e93c502002-04-12 11:12:52 +00002656 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002657 break;
2658
2659 case __NR_unlink: /* syscall 10 */
2660 /* int unlink(const char *pathname) */
2661 if (VG_(clo_trace_syscalls))
2662 VG_(printf)("ulink ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002663 must_be_readable_asciiz( tst, "unlink(pathname)", arg1 );
sewardj2e93c502002-04-12 11:12:52 +00002664 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002665 break;
2666
2667 case __NR_uname: /* syscall 122 */
2668 /* int uname(struct utsname *buf); */
2669 if (VG_(clo_trace_syscalls))
2670 VG_(printf)("uname ( %p )\n",arg1);
sewardj8c824512002-04-14 04:16:48 +00002671 must_be_writable( tst, "uname(buf)", arg1, sizeof(struct utsname) );
sewardj2e93c502002-04-12 11:12:52 +00002672 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002673 if (!VG_(is_kerror)(res) && arg1 != (UInt)NULL) {
2674 make_readable( arg1, sizeof(struct utsname) );
2675 }
2676 break;
2677
2678 case __NR_utime: /* syscall 30 */
2679 /* int utime(const char *filename, struct utimbuf *buf); */
2680 if (VG_(clo_trace_syscalls))
2681 VG_(printf)("utime ( %p, %p )\n", arg1,arg2);
sewardj8c824512002-04-14 04:16:48 +00002682 must_be_readable_asciiz( tst, "utime(filename)", arg1 );
sewardjde4a1d02002-03-22 01:27:54 +00002683 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002684 must_be_readable( tst, "utime(buf)", arg2,
2685 sizeof(struct utimbuf) );
sewardj2e93c502002-04-12 11:12:52 +00002686 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002687 break;
2688
2689 case __NR_wait4: /* syscall 114 */
2690 /* pid_t wait4(pid_t pid, int *status, int options,
2691 struct rusage *rusage) */
2692 if (VG_(clo_trace_syscalls))
2693 VG_(printf)("wait4 ( %d, %p, %d, %p )\n",
2694 arg1,arg2,arg3,arg4);
2695 if (arg2 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002696 must_be_writable( tst, "wait4(status)", arg2, sizeof(int) );
sewardjde4a1d02002-03-22 01:27:54 +00002697 if (arg4 != (Addr)NULL)
sewardj8c824512002-04-14 04:16:48 +00002698 must_be_writable( tst, "wait4(rusage)", arg4,
2699 sizeof(struct rusage) );
sewardj2e93c502002-04-12 11:12:52 +00002700 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002701 if (!VG_(is_kerror)(res)) {
2702 if (arg2 != (Addr)NULL)
2703 make_readable( arg2, sizeof(int) );
2704 if (arg4 != (Addr)NULL)
2705 make_readable( arg4, sizeof(struct rusage) );
2706 }
2707 break;
2708
sewardjde4a1d02002-03-22 01:27:54 +00002709 case __NR_writev: { /* syscall 146 */
2710 /* int writev(int fd, const struct iovec * vector, size_t count); */
2711 UInt i;
2712 struct iovec * vec;
2713 if (VG_(clo_trace_syscalls))
2714 VG_(printf)("writev ( %d, %p, %d )\n",arg1,arg2,arg3);
sewardj8c824512002-04-14 04:16:48 +00002715 must_be_readable( tst, "writev(vector)",
sewardjde4a1d02002-03-22 01:27:54 +00002716 arg2, arg3 * sizeof(struct iovec) );
2717 /* ToDo: don't do any of the following if the vector is invalid */
2718 vec = (struct iovec *)arg2;
2719 for (i = 0; i < arg3; i++)
sewardj8c824512002-04-14 04:16:48 +00002720 must_be_readable( tst, "writev(vector[...])",
sewardjde4a1d02002-03-22 01:27:54 +00002721 (UInt)vec[i].iov_base,vec[i].iov_len );
sewardj2e93c502002-04-12 11:12:52 +00002722 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002723 break;
2724 }
2725
2726 /*-------------------------- SIGNALS --------------------------*/
2727
2728 /* Normally set to 1, so that Valgrind's signal-simulation machinery
2729 is engaged. Sometimes useful to disable (set to 0), for
2730 debugging purposes, to make clients more deterministic. */
2731# define SIGNAL_SIMULATION 1
2732
2733 case __NR_rt_sigaction:
2734 case __NR_sigaction:
2735 /* int sigaction(int signum, struct k_sigaction *act,
2736 struct k_sigaction *oldact); */
2737 if (VG_(clo_trace_syscalls))
2738 VG_(printf)("sigaction ( %d, %p, %p )\n",arg1,arg2,arg3);
2739 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002740 must_be_readable( tst, "sigaction(act)",
sewardjde4a1d02002-03-22 01:27:54 +00002741 arg2, sizeof(vki_ksigaction));
2742 if (arg3 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002743 must_be_writable( tst, "sigaction(oldact)",
sewardjde4a1d02002-03-22 01:27:54 +00002744 arg3, sizeof(vki_ksigaction));
2745 /* We do this one ourselves! */
2746# if SIGNAL_SIMULATION
sewardj2e93c502002-04-12 11:12:52 +00002747 VG_(do__NR_sigaction)(tid);
2748 res = tst->m_eax;
sewardjde4a1d02002-03-22 01:27:54 +00002749# else
2750 /* debugging signals; when we don't handle them. */
sewardj2e93c502002-04-12 11:12:52 +00002751 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002752# endif
2753 if (!VG_(is_kerror)(res) && res == 0 && arg3 != (UInt)NULL)
2754 make_readable( arg3, sizeof(vki_ksigaction));
2755 break;
2756
2757 case __NR_rt_sigprocmask:
2758 case __NR_sigprocmask:
2759 /* int sigprocmask(int how, k_sigset_t *set,
2760 k_sigset_t *oldset); */
2761 if (VG_(clo_trace_syscalls))
2762 VG_(printf)("sigprocmask ( %d, %p, %p )\n",arg1,arg2,arg3);
2763 if (arg2 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002764 must_be_readable( tst, "sigprocmask(set)",
sewardjde4a1d02002-03-22 01:27:54 +00002765 arg2, sizeof(vki_ksigset_t));
2766 if (arg3 != (UInt)NULL)
sewardj8c824512002-04-14 04:16:48 +00002767 must_be_writable( tst, "sigprocmask(oldset)",
sewardjde4a1d02002-03-22 01:27:54 +00002768 arg3, sizeof(vki_ksigset_t));
sewardj2e93c502002-04-12 11:12:52 +00002769 KERNEL_DO_SYSCALL(tid,res);
sewardjde4a1d02002-03-22 01:27:54 +00002770 if (!VG_(is_kerror)(res) && res == 0 && arg3 != (UInt)NULL)
2771 make_readable( arg3, sizeof(vki_ksigset_t));
2772# if SIGNAL_SIMULATION
2773 /* For the reason why both the kernel and Valgrind process
2774 sigprocmask, see the detailed comment at
2775 vg_do__NR_sigprocmask(). */
2776 VG_(do__NR_sigprocmask) ( arg1 /*how*/, (vki_ksigset_t*) arg2 );
2777# endif
2778 break;
2779
2780 default:
2781 VG_(message)
2782 (Vg_DebugMsg,"FATAL: unhandled syscall: %d",syscallno);
2783 VG_(message)
2784 (Vg_DebugMsg,"Do not panic. You may be able to fix this easily.");
2785 VG_(message)
2786 (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
2787 VG_(unimplemented)("no wrapper for the above system call");
2788 vg_assert(3+3 == 7);
2789 break; /*NOTREACHED*/
2790 }
2791
sewardjde4a1d02002-03-22 01:27:54 +00002792 /* { void zzzmemscan(void); zzzmemscan(); } */
2793
sewardjde4a1d02002-03-22 01:27:54 +00002794 if (! VG_(first_and_last_secondaries_look_plausible))
2795 sane_before_call = False;
2796
2797 if (sane_before_call && (!sane_after_call)) {
sewardj2e93c502002-04-12 11:12:52 +00002798 VG_(message)(Vg_DebugMsg, "perform_assumed_nonblocking_syscall: ");
sewardjde4a1d02002-03-22 01:27:54 +00002799 VG_(message)(Vg_DebugMsg,
2800 "probable sanity check failure for syscall number %d\n",
2801 syscallno );
2802 VG_(panic)("aborting due to the above ... bye!");
2803 }
2804
2805 VGP_POPCC;
2806}
2807
2808
sewardj2e93c502002-04-12 11:12:52 +00002809
2810/* Perform pre- and post- actions for a blocking syscall, but do not
2811 do the syscall itself. If res is NULL, the pre-syscall actions are
2812 to be performed. If res is non-NULL, the post-syscall actions are
2813 to be performed, and *res is assumed to hold the result of the
2814 syscall. This slightly strange scheme makes it impossible to
2815 mistakenly use the value of *res in the pre-syscall actions.
2816
2817 This doesn't actually do the syscall itself, it is important to
2818 observe.
2819
2820 Because %eax is used both for the syscall number before the call
2821 and the result value afterwards, we can't reliably use it to get
2822 the syscall number. So the caller has to pass it explicitly.
2823*/
sewardj8c824512002-04-14 04:16:48 +00002824void VG_(check_known_blocking_syscall) ( ThreadId tid,
sewardj2e93c502002-04-12 11:12:52 +00002825 Int syscallno,
2826 Int* /*IN*/ res )
2827{
2828 Bool sane_before_post = True;
2829 Bool sane_after_post = True;
2830 ThreadState* tst = VG_(get_thread_state)( tid );
2831 UInt arg1 = tst->m_ebx;
2832 UInt arg2 = tst->m_ecx;
2833 UInt arg3 = tst->m_edx;
2834 /*
2835 UInt arg4 = tst->m_esi;
2836 UInt arg5 = tst->m_edi;
2837 */
2838 VGP_PUSHCC(VgpSyscall);
2839
2840 if (res != NULL
2841 && ! VG_(first_and_last_secondaries_look_plausible))
2842 sane_before_post = False;
2843
2844 switch (syscallno) {
2845
2846 case __NR_read: /* syscall 3 */
2847 /* size_t read(int fd, void *buf, size_t count); */
2848 if (res == NULL) {
2849 /* PRE */
2850 if (VG_(clo_trace_syscalls))
2851 VG_(printf)(
2852 "SYSCALL--PRE[%d,%d] read ( %d, %p, %d )\n",
2853 VG_(getpid)(), tid,
2854 arg1, arg2, arg3);
sewardj8c824512002-04-14 04:16:48 +00002855 must_be_writable( tst, "read(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +00002856 } else {
2857 /* POST */
2858 if (VG_(clo_trace_syscalls))
2859 VG_(printf)(
2860 "SYSCALL-POST[%d,%d] read ( %d, %p, %d ) --> %d\n",
2861 VG_(getpid)(), tid,
2862 arg1, arg2, arg3, *res);
2863 if (!VG_(is_kerror)(*res) && *res > 0) {
2864 make_readable( arg2, *res );
2865 }
2866 }
2867 break;
2868
2869 case __NR_write: /* syscall 4 */
2870 /* size_t write(int fd, const void *buf, size_t count); */
2871 if (res == NULL) {
2872 /* PRE */
2873 if (VG_(clo_trace_syscalls))
2874 VG_(printf)(
2875 "SYSCALL--PRE[%d,%d] write ( %d, %p, %d )\n",
2876 VG_(getpid)(), tid,
2877 arg1, arg2, arg3);
sewardj8c824512002-04-14 04:16:48 +00002878 must_be_readable( tst, "write(buf)", arg2, arg3 );
sewardj2e93c502002-04-12 11:12:52 +00002879 } else {
2880 /* POST */
2881 if (VG_(clo_trace_syscalls))
2882 VG_(printf)(
2883 "SYSCALL-POST[%d,%d] write ( %d, %p, %d ) --> %d\n",
2884 VG_(getpid)(), tid,
2885 arg1, arg2, arg3, *res);
2886 }
2887 break;
2888
2889 default:
2890 VG_(printf)("check_known_blocking_syscall: unexpected %d\n",
2891 syscallno);
2892 VG_(panic)("check_known_blocking_syscall");
2893 /*NOTREACHED*/
2894 break;
2895 }
2896
2897 if (res != NULL) { /* only check after syscall */
2898 if (! VG_(first_and_last_secondaries_look_plausible))
2899 sane_after_post = False;
2900
2901 if (sane_before_post && (!sane_after_post)) {
2902 VG_(message)(Vg_DebugMsg, "perform_known_blocking_syscall: ");
2903 VG_(message)(Vg_DebugMsg,
2904 "probable sanity check failure for syscall number %d\n",
2905 syscallno );
2906 VG_(panic)("aborting due to the above ... bye!");
2907 }
2908 }
2909
2910 VGP_POPCC;
2911}
2912
2913
sewardjde4a1d02002-03-22 01:27:54 +00002914/*--------------------------------------------------------------------*/
2915/*--- end vg_syscall_mem.c ---*/
2916/*--------------------------------------------------------------------*/