blob: 3812e19631565d1d9846c4000b4be1f690f336af [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njnc1b01812005-06-17 22:19:06 +00003/*--- Wrappers for generic Unix system calls syswrap-generic.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardje4b0bf02006-06-05 23:21:15 +000010 Copyright (C) 2000-2006 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
32#include "pub_core_threadstate.h"
sewardj45f4e7c2005-09-27 19:20:21 +000033#include "pub_core_debuginfo.h" // VG_(di_notify_*)
sewardj55f9d1a2005-04-25 11:11:44 +000034#include "pub_core_aspacemgr.h"
sewardj45f4e7c2005-09-27 19:20:21 +000035#include "pub_core_transtab.h" // VG_(discard_translations)
36#include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit)
njn899ce732005-06-21 00:28:11 +000037#include "pub_core_debuglog.h"
njn0087c502005-07-01 04:15:36 +000038#include "pub_core_errormgr.h"
njn97405b22005-06-02 03:39:33 +000039#include "pub_core_libcbase.h"
sewardja8d8e232005-06-07 20:04:56 +000040#include "pub_core_libcassert.h"
njnde62cbf2005-06-10 22:08:14 +000041#include "pub_core_libcfile.h"
42#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000043#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000044#include "pub_core_libcsignal.h"
njnaf1d7df2005-06-11 01:31:52 +000045#include "pub_core_mallocfree.h"
sewardja8d8e232005-06-07 20:04:56 +000046#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +000047#include "pub_core_scheduler.h"
sewardja8d8e232005-06-07 20:04:56 +000048#include "pub_core_signals.h"
njn419bbcb2005-06-21 03:52:49 +000049#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +000050#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +000051#include "pub_core_syswrap.h"
njn419bbcb2005-06-21 03:52:49 +000052#include "pub_core_tooliface.h"
njn73750612005-10-14 03:11:30 +000053#include "pub_core_ume.h"
sewardj55f9d1a2005-04-25 11:11:44 +000054
sewardja8d8e232005-06-07 20:04:56 +000055#include "priv_types_n_macros.h"
njnc1b01812005-06-17 22:19:06 +000056#include "priv_syswrap-generic.h"
sewardjde4a1d02002-03-22 01:27:54 +000057
sewardj4eee4762006-10-14 15:51:32 +000058#include "pub_core_vkiscnums.h" /* for the __NR_* constants */
sewardjde4a1d02002-03-22 01:27:54 +000059
jsgf855d93d2003-10-13 22:26:55 +000060
sewardj45f4e7c2005-09-27 19:20:21 +000061/* Returns True iff address range is something the client can
62 plausibly mess with: all of it is either already belongs to the
63 client or is free or a reservation. */
64
sewardj7eb7c582005-06-23 01:02:53 +000065Bool ML_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
nethercote8ff888f2004-11-17 17:11:45 +000066 const Char *syscallname)
fitzhardinge1a303042003-12-22 08:48:50 +000067{
fitzhardinge1a303042003-12-22 08:48:50 +000068 Bool ret;
69
70 if (size == 0)
71 return True;
72
sewardj45f4e7c2005-09-27 19:20:21 +000073 ret = VG_(am_is_valid_for_client_or_free_or_resvn)
74 (start,size,VKI_PROT_NONE);
fitzhardinge1a303042003-12-22 08:48:50 +000075
76 if (0)
sewardj45f4e7c2005-09-27 19:20:21 +000077 VG_(printf)("%s: test=%p-%p ret=%d\n",
78 syscallname, start, start+size-1, (Int)ret);
fitzhardinge1a303042003-12-22 08:48:50 +000079
nethercote1543adf2004-10-25 15:43:21 +000080 if (!ret && syscallname != NULL) {
sewardja8d8e232005-06-07 20:04:56 +000081 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
82 "to modify addresses %p-%p",
sewardj8a8934d2006-01-03 04:09:27 +000083 syscallname, (void*)start, (void*)(start+size-1));
fitzhardinge1a303042003-12-22 08:48:50 +000084 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +000085 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge1a303042003-12-22 08:48:50 +000086 }
87 }
88
89 return ret;
90}
91
sewardj45f4e7c2005-09-27 19:20:21 +000092
sewardj7eb7c582005-06-23 01:02:53 +000093Bool ML_(client_signal_OK)(Int sigNo)
njn419bbcb2005-06-21 03:52:49 +000094{
95 /* signal 0 is OK for kill */
njn351d0062005-06-21 22:23:59 +000096 Bool ret = sigNo >= 0 && sigNo <= VG_SIGVGRTUSERMAX;
njn419bbcb2005-06-21 03:52:49 +000097
98 //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret);
99
100 return ret;
101}
102
sewardj45f4e7c2005-09-27 19:20:21 +0000103
104/* Handy small function to help stop wrappers from segfaulting when
105 presented with bogus client addresses. Is not used for generating
106 user-visible errors. */
107
108Bool ML_(safe_to_deref) ( void* start, SizeT size )
109{
110 return VG_(am_is_valid_for_client)( (Addr)start, size, VKI_PROT_NONE );
111}
112
113
njn25e49d8e72002-09-23 09:36:25 +0000114/* ---------------------------------------------------------------------
nethercote27ea8bc2004-07-10 17:21:14 +0000115 Doing mmap, mremap
njn25e49d8e72002-09-23 09:36:25 +0000116 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000117
njn25e49d8e72002-09-23 09:36:25 +0000118// Nb: this isn't done as precisely as possible, but it seems that programs
119// are usually sufficiently well-behaved that the more obscure corner cases
120// aren't important. Various comments in the few functions below give more
121// details... njn 2002-Sep-17
122
123/* AFAICT from kernel sources (mm/mprotect.c) and general experimentation,
124 munmap, mprotect (and mremap??) work at the page level. So addresses
125 and lengths must be adjusted for this. */
126
127/* Mash around start and length so that the area exactly covers
128 an integral number of pages. If we don't do that, memcheck's
129 idea of addressible memory diverges from that of the
130 kernel's, which causes the leak detector to crash. */
131static
sewardj45f4e7c2005-09-27 19:20:21 +0000132void page_align_addr_and_len( Addr* a, SizeT* len)
sewardjde4a1d02002-03-22 01:27:54 +0000133{
fitzhardinge98abfc72003-12-16 02:05:15 +0000134 Addr ra;
135
njn13bfd852005-06-02 03:52:53 +0000136 ra = VG_PGROUNDDN(*a);
137 *len = VG_PGROUNDUP(*a + *len) - ra;
fitzhardinge98abfc72003-12-16 02:05:15 +0000138 *a = ra;
sewardjde4a1d02002-03-22 01:27:54 +0000139}
140
sewardj45f4e7c2005-09-27 19:20:21 +0000141/* When a client mmap has been successfully done, this function must
142 be called. It notifies both aspacem and the tool of the new
143 mapping.
144*/
145void
146ML_(notify_aspacem_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot,
sewardj274461d2005-10-02 17:01:41 +0000147 UInt flags, Int fd, Off64T offset )
sewardjde4a1d02002-03-22 01:27:54 +0000148{
sewardj45f4e7c2005-09-27 19:20:21 +0000149 Bool rr, ww, xx, d;
njn25e49d8e72002-09-23 09:36:25 +0000150
sewardj45f4e7c2005-09-27 19:20:21 +0000151 /* 'a' is the return value from a real kernel mmap, hence: */
152 vg_assert(VG_IS_PAGE_ALIGNED(a));
153 /* whereas len is whatever the syscall supplied. So: */
154 len = VG_PGROUNDUP(len);
fitzhardinge98abfc72003-12-16 02:05:15 +0000155
sewardj45f4e7c2005-09-27 19:20:21 +0000156 d = VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset );
fitzhardinge98abfc72003-12-16 02:05:15 +0000157
sewardj45f4e7c2005-09-27 19:20:21 +0000158 rr = toBool(prot & VKI_PROT_READ);
159 ww = toBool(prot & VKI_PROT_WRITE);
160 xx = toBool(prot & VKI_PROT_EXEC);
njn25e49d8e72002-09-23 09:36:25 +0000161
sewardj40f8ebe2002-10-23 21:46:13 +0000162 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
sewardj45f4e7c2005-09-27 19:20:21 +0000163
164 if (d)
165 VG_(discard_translations)( (Addr64)a, (ULong)len,
166 "ML_(notify_aspacem_and_tool_of_mmap)" );
sewardjde4a1d02002-03-22 01:27:54 +0000167}
168
sewardj45f4e7c2005-09-27 19:20:21 +0000169/* Expand (or shrink) an existing mapping, potentially moving it at
170 the same time (controlled by the MREMAP_MAYMOVE flag). Nightmare.
171*/
172static
173SysRes do_mremap( Addr old_addr, SizeT old_len,
174 Addr new_addr, SizeT new_len,
175 UWord flags, ThreadId tid )
njn25e49d8e72002-09-23 09:36:25 +0000176{
sewardj45f4e7c2005-09-27 19:20:21 +0000177# define MIN_SIZET(_aa,_bb) (_aa) < (_bb) ? (_aa) : (_bb)
njn25e49d8e72002-09-23 09:36:25 +0000178
sewardj45f4e7c2005-09-27 19:20:21 +0000179 Bool ok, d;
180 NSegment* old_seg;
181 Addr advised;
182 Bool f_fixed = toBool(flags & VKI_MREMAP_FIXED);
183 Bool f_maymove = toBool(flags & VKI_MREMAP_MAYMOVE);
fitzhardinge1a303042003-12-22 08:48:50 +0000184
185 if (0)
sewardj45f4e7c2005-09-27 19:20:21 +0000186 VG_(printf)("do_remap (old %p %d) (new %p %d) %s %s\n",
187 old_addr,old_len,new_addr,new_len,
188 flags & VKI_MREMAP_MAYMOVE ? "MAYMOVE" : "",
189 flags & VKI_MREMAP_FIXED ? "FIXED" : "");
sewardj63a622f2006-08-16 14:22:29 +0000190 if (0)
191 VG_(am_show_nsegments)(0, "do_remap: before");
fitzhardinge1a303042003-12-22 08:48:50 +0000192
sewardj45f4e7c2005-09-27 19:20:21 +0000193 if (flags & ~(VKI_MREMAP_FIXED | VKI_MREMAP_MAYMOVE))
194 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000195
sewardj45f4e7c2005-09-27 19:20:21 +0000196 if (!VG_IS_PAGE_ALIGNED(old_addr))
197 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000198
sewardj45f4e7c2005-09-27 19:20:21 +0000199 old_len = VG_PGROUNDUP(old_len);
200 new_len = VG_PGROUNDUP(new_len);
fitzhardinge1a303042003-12-22 08:48:50 +0000201
sewardj45f4e7c2005-09-27 19:20:21 +0000202 if (new_len == 0)
203 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000204
sewardj45f4e7c2005-09-27 19:20:21 +0000205 /* kernel doesn't reject this, but we do. */
206 if (old_len == 0)
207 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000208
sewardj45f4e7c2005-09-27 19:20:21 +0000209 /* reject wraparounds */
210 if (old_addr + old_len < old_addr
211 || new_addr + new_len < new_len)
212 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000213
sewardj45f4e7c2005-09-27 19:20:21 +0000214 /* kernel rejects all fixed, no-move requests (which are
215 meaningless). */
216 if (f_fixed == True && f_maymove == False)
217 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000218
sewardj45f4e7c2005-09-27 19:20:21 +0000219 /* Stay away from non-client areas. */
220 if (!ML_(valid_client_addr)(old_addr, old_len, tid, "mremap(old_addr)"))
221 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000222
sewardj45f4e7c2005-09-27 19:20:21 +0000223 /* In all remaining cases, if the old range does not fall within a
224 single segment, fail. */
225 old_seg = VG_(am_find_nsegment)( old_addr );
226 if (old_addr < old_seg->start || old_addr+old_len-1 > old_seg->end)
227 goto eINVAL;
sewardjfdf619e2005-11-23 03:41:41 +0000228 if (old_seg->kind != SkAnonC && old_seg->kind != SkFileC)
sewardj45f4e7c2005-09-27 19:20:21 +0000229 goto eINVAL;
fitzhardinge1a303042003-12-22 08:48:50 +0000230
sewardj45f4e7c2005-09-27 19:20:21 +0000231 vg_assert(old_len > 0);
232 vg_assert(new_len > 0);
233 vg_assert(VG_IS_PAGE_ALIGNED(old_len));
234 vg_assert(VG_IS_PAGE_ALIGNED(new_len));
235 vg_assert(VG_IS_PAGE_ALIGNED(old_addr));
fitzhardinge1a303042003-12-22 08:48:50 +0000236
sewardj45f4e7c2005-09-27 19:20:21 +0000237 /* There are 3 remaining cases:
fitzhardinge1a303042003-12-22 08:48:50 +0000238
sewardj45f4e7c2005-09-27 19:20:21 +0000239 * maymove == False
240
241 new space has to be at old address, so:
242 - shrink -> unmap end
243 - same size -> do nothing
244 - grow -> if can grow in-place, do so, else fail
245
246 * maymove == True, fixed == False
247
248 new space can be anywhere, so:
249 - shrink -> unmap end
250 - same size -> do nothing
251 - grow -> if can grow in-place, do so, else
252 move to anywhere large enough, else fail
253
254 * maymove == True, fixed == True
255
256 new space must be at new address, so:
257
258 - if new address is not page aligned, fail
259 - if new address range overlaps old one, fail
260 - if new address range cannot be allocated, fail
261 - else move to new address range with new size
262 - else fail
263 */
264
265 if (f_maymove == False) {
266 /* new space has to be at old address */
267 if (new_len < old_len)
268 goto shrink_in_place;
269 if (new_len > old_len)
270 goto grow_in_place_or_fail;
271 goto same_in_place;
272 }
273
274 if (f_maymove == True && f_fixed == False) {
275 /* new space can be anywhere */
276 if (new_len < old_len)
277 goto shrink_in_place;
278 if (new_len > old_len)
279 goto grow_in_place_or_move_anywhere_or_fail;
280 goto same_in_place;
281 }
282
283 if (f_maymove == True && f_fixed == True) {
284 /* new space can only be at the new address */
285 if (!VG_IS_PAGE_ALIGNED(new_addr))
286 goto eINVAL;
287 if (new_addr+new_len-1 < old_addr || new_addr > old_addr+old_len-1) {
288 /* no overlap */
fitzhardinge1a303042003-12-22 08:48:50 +0000289 } else {
sewardj45f4e7c2005-09-27 19:20:21 +0000290 goto eINVAL;
291 }
292 if (new_addr == 0)
293 goto eINVAL;
294 /* VG_(am_get_advisory_client_simple) interprets zero to mean
295 non-fixed, which is not what we want */
296 advised = VG_(am_get_advisory_client_simple)(new_addr, new_len, &ok);
297 if (!ok || advised != new_addr)
298 goto eNOMEM;
299 ok = VG_(am_relocate_nooverlap_client)
300 ( &d, old_addr, old_len, new_addr, new_len );
301 if (ok) {
302 VG_TRACK( copy_mem_remap, old_addr, new_addr,
303 MIN_SIZET(old_len,new_len) );
304 if (new_len > old_len)
305 VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len,
306 old_seg->hasR, old_seg->hasW, old_seg->hasX );
307 VG_TRACK(die_mem_munmap, old_addr, old_len);
308 if (d) {
309 VG_(discard_translations)( old_addr, old_len, "do_remap(1)" );
310 VG_(discard_translations)( new_addr, new_len, "do_remap(2)" );
311 }
312 return VG_(mk_SysRes_Success)( new_addr );
313 }
314 goto eNOMEM;
315 }
fitzhardinge1a303042003-12-22 08:48:50 +0000316
sewardj45f4e7c2005-09-27 19:20:21 +0000317 /* end of the 3 cases */
318 /*NOTREACHED*/ vg_assert(0);
fitzhardinge1a303042003-12-22 08:48:50 +0000319
sewardj45f4e7c2005-09-27 19:20:21 +0000320 grow_in_place_or_move_anywhere_or_fail:
321 {
322 /* try growing it in-place */
323 Addr needA = old_addr + old_len;
324 SSizeT needL = new_len - old_len;
fitzhardinge1a303042003-12-22 08:48:50 +0000325
sewardj45f4e7c2005-09-27 19:20:21 +0000326 vg_assert(needL > 0);
327 if (needA == 0)
328 goto eINVAL;
329 /* VG_(am_get_advisory_client_simple) interprets zero to mean
330 non-fixed, which is not what we want */
331 advised = VG_(am_get_advisory_client_simple)( needA, needL, &ok );
sewardj63a622f2006-08-16 14:22:29 +0000332 if (ok) {
333 /* VG_(am_get_advisory_client_simple) (first arg == 0, meaning
334 this-or-nothing) is too lenient, and may allow us to trash
335 the next segment along. So make very sure that the proposed
336 new area really is free. This is perhaps overly
337 conservative, but it fixes #129866. */
338 NSegment* segLo = VG_(am_find_nsegment)( needA );
339 NSegment* segHi = VG_(am_find_nsegment)( needA + needL - 1 );
340 if (segLo == NULL || segHi == NULL
341 || segLo != segHi || segLo->kind != SkFree)
342 ok = False;
343 }
sewardj45f4e7c2005-09-27 19:20:21 +0000344 if (ok && advised == needA) {
345 ok = VG_(am_extend_map_client)( &d, old_seg, needL );
346 if (ok) {
347 VG_TRACK( new_mem_mmap, needA, needL,
348 old_seg->hasR,
349 old_seg->hasW, old_seg->hasX );
350 if (d)
351 VG_(discard_translations)( needA, needL, "do_remap(3)" );
352 return VG_(mk_SysRes_Success)( old_addr );
fitzhardinge1a303042003-12-22 08:48:50 +0000353 }
354 }
355
sewardj45f4e7c2005-09-27 19:20:21 +0000356 /* that failed. Look elsewhere. */
357 advised = VG_(am_get_advisory_client_simple)( 0, new_len, &ok );
358 if (ok) {
359 /* assert new area does not overlap old */
360 vg_assert(advised+new_len-1 < old_addr
361 || advised > old_addr+old_len-1);
362 ok = VG_(am_relocate_nooverlap_client)
363 ( &d, old_addr, old_len, advised, new_len );
364 if (ok) {
365 VG_TRACK( copy_mem_remap, old_addr, advised,
366 MIN_SIZET(old_len,new_len) );
367 if (new_len > old_len)
368 VG_TRACK( new_mem_mmap, advised+old_len, new_len-old_len,
369 old_seg->hasR, old_seg->hasW, old_seg->hasX );
370 VG_TRACK(die_mem_munmap, old_addr, old_len);
371 if (d) {
372 VG_(discard_translations)( old_addr, old_len, "do_remap(4)" );
373 VG_(discard_translations)( advised, new_len, "do_remap(5)" );
374 }
375 return VG_(mk_SysRes_Success)( advised );
376 }
377 }
378 goto eNOMEM;
379 }
380 /*NOTREACHED*/ vg_assert(0);
381
382 grow_in_place_or_fail:
383 {
384 Addr needA = old_addr + old_len;
385 SizeT needL = new_len - old_len;
386 if (needA == 0)
387 goto eINVAL;
388 /* VG_(am_get_advisory_client_simple) interprets zero to mean
389 non-fixed, which is not what we want */
390 advised = VG_(am_get_advisory_client_simple)( needA, needL, &ok );
sewardj63a622f2006-08-16 14:22:29 +0000391 if (ok) {
392 /* VG_(am_get_advisory_client_simple) (first arg == 0, meaning
393 this-or-nothing) is too lenient, and may allow us to trash
394 the next segment along. So make very sure that the proposed
395 new area really is free. */
396 NSegment* segLo = VG_(am_find_nsegment)( needA );
397 NSegment* segHi = VG_(am_find_nsegment)( needA + needL - 1 );
398 if (segLo == NULL || segHi == NULL
399 || segLo != segHi || segLo->kind != SkFree)
400 ok = False;
401 }
sewardj45f4e7c2005-09-27 19:20:21 +0000402 if (!ok || advised != needA)
403 goto eNOMEM;
404 ok = VG_(am_extend_map_client)( &d, old_seg, needL );
405 if (!ok)
406 goto eNOMEM;
407 VG_TRACK( new_mem_mmap, needA, needL,
408 old_seg->hasR, old_seg->hasW, old_seg->hasX );
409 if (d)
410 VG_(discard_translations)( needA, needL, "do_remap(6)" );
411 return VG_(mk_SysRes_Success)( old_addr );
412 }
413 /*NOTREACHED*/ vg_assert(0);
414
415 shrink_in_place:
416 {
417 SysRes sres = VG_(am_munmap_client)( &d, old_addr+new_len, old_len-new_len );
418 if (sres.isError)
419 return sres;
420 VG_TRACK( die_mem_munmap, old_addr+new_len, old_len-new_len );
421 if (d)
422 VG_(discard_translations)( old_addr+new_len, old_len-new_len,
423 "do_remap(7)" );
424 return VG_(mk_SysRes_Success)( old_addr );
425 }
426 /*NOTREACHED*/ vg_assert(0);
427
428 same_in_place:
429 return VG_(mk_SysRes_Success)( old_addr );
430 /*NOTREACHED*/ vg_assert(0);
431
432 eINVAL:
433 return VG_(mk_SysRes_Error)( VKI_EINVAL );
434 eNOMEM:
435 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
436
437# undef MIN_SIZET
sewardjde4a1d02002-03-22 01:27:54 +0000438}
439
440
sewardja8d8e232005-06-07 20:04:56 +0000441/* ---------------------------------------------------------------------
442 File-descriptor tracking
443 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000444
rjwalshf5f536f2003-11-17 17:45:00 +0000445/* One of these is allocated for each open file descriptor. */
rjwalshf5f536f2003-11-17 17:45:00 +0000446typedef struct OpenFd
447{
448 Int fd; /* The file descriptor */
449 Char *pathname; /* NULL if not a regular file or unknown */
450 ExeContext *where; /* NULL if inherited from parent */
451 struct OpenFd *next, *prev;
452} OpenFd;
453
454/* List of allocated file descriptors. */
rjwalshf5f536f2003-11-17 17:45:00 +0000455static OpenFd *allocated_fds;
456
457/* Count of open file descriptors. */
sewardj0a400c72005-07-23 09:22:46 +0000458static Int fd_count = 0;
rjwalshf5f536f2003-11-17 17:45:00 +0000459
rjwalshf5f536f2003-11-17 17:45:00 +0000460
rjwalshf5f536f2003-11-17 17:45:00 +0000461/* Note the fact that a file descriptor was just closed. */
rjwalshf5f536f2003-11-17 17:45:00 +0000462static
njnc6168192004-11-29 13:54:10 +0000463void record_fd_close(ThreadId tid, Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000464{
465 OpenFd *i = allocated_fds;
466
thughesad1c9562004-06-26 11:27:52 +0000467 if (fd >= VG_(fd_hard_limit))
rjwalsh02665ba2003-12-18 01:48:06 +0000468 return; /* Valgrind internal */
469
rjwalshf5f536f2003-11-17 17:45:00 +0000470 while(i) {
471 if(i->fd == fd) {
472 if(i->prev)
473 i->prev->next = i->next;
474 else
475 allocated_fds = i->next;
476 if(i->next)
477 i->next->prev = i->prev;
478 if(i->pathname)
fitzhardingea7728472003-12-16 01:48:38 +0000479 VG_(arena_free) (VG_AR_CORE, i->pathname);
480 VG_(arena_free) (VG_AR_CORE, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000481 fd_count--;
482 break;
483 }
484 i = i->next;
485 }
486}
487
488/* Note the fact that a file descriptor was just opened. If the
489 tid is -1, this indicates an inherited fd. If the pathname is NULL,
490 this either indicates a non-standard file (i.e. a pipe or socket or
491 some such thing) or that we don't know the filename. If the fd is
492 already open, then we're probably doing a dup2() to an existing fd,
493 so just overwrite the existing one. */
njn4279a882005-08-26 03:43:28 +0000494void ML_(record_fd_open_with_given_name)(ThreadId tid, Int fd, char *pathname)
rjwalshf5f536f2003-11-17 17:45:00 +0000495{
496 OpenFd *i;
497
thughesad1c9562004-06-26 11:27:52 +0000498 if (fd >= VG_(fd_hard_limit))
fitzhardinge0e8bfcf2003-12-12 07:46:54 +0000499 return; /* Valgrind internal */
500
rjwalshf5f536f2003-11-17 17:45:00 +0000501 /* Check to see if this fd is already open. */
502 i = allocated_fds;
503 while (i) {
504 if (i->fd == fd) {
fitzhardingea7728472003-12-16 01:48:38 +0000505 if (i->pathname) VG_(arena_free)(VG_AR_CORE, i->pathname);
rjwalshf5f536f2003-11-17 17:45:00 +0000506 break;
507 }
508 i = i->next;
509 }
510
511 /* Not already one: allocate an OpenFd */
512 if (i == NULL) {
fitzhardingea7728472003-12-16 01:48:38 +0000513 i = VG_(arena_malloc)(VG_AR_CORE, sizeof(OpenFd));
rjwalshf5f536f2003-11-17 17:45:00 +0000514
515 i->prev = NULL;
516 i->next = allocated_fds;
517 if(allocated_fds) allocated_fds->prev = i;
518 allocated_fds = i;
519 fd_count++;
520 }
521
522 i->fd = fd;
njnf845f8f2005-06-23 02:26:47 +0000523 i->pathname = VG_(arena_strdup)(VG_AR_CORE, pathname);
njnd01fef72005-03-25 23:35:48 +0000524 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid);
rjwalshf5f536f2003-11-17 17:45:00 +0000525}
526
njnf845f8f2005-06-23 02:26:47 +0000527// Record opening of an fd, and find its name.
528static void record_fd_open_named(ThreadId tid, Int fd)
529{
530 static HChar buf[VKI_PATH_MAX];
531 Char* name;
532 if (VG_(resolve_filename)(fd, buf, VKI_PATH_MAX))
533 name = buf;
534 else
535 name = NULL;
536
njn4279a882005-08-26 03:43:28 +0000537 ML_(record_fd_open_with_given_name)(tid, fd, name);
njnf845f8f2005-06-23 02:26:47 +0000538}
539
540// Record opening of a nameless fd.
541void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
542{
njn4279a882005-08-26 03:43:28 +0000543 ML_(record_fd_open_with_given_name)(tid, fd, NULL);
njnf845f8f2005-06-23 02:26:47 +0000544}
545
rjwalshf5f536f2003-11-17 17:45:00 +0000546static
nethercote73b526f2004-10-31 18:48:21 +0000547Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000548{
nethercote73b526f2004-10-31 18:48:21 +0000549 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
rjwalshf5f536f2003-11-17 17:45:00 +0000550 VG_(sprintf)(name, "<unknown>");
551 } else {
552 VG_(sprintf)(name, "%s", sa->sun_path);
553 }
554
555 return name;
556}
557
558static
nethercote73b526f2004-10-31 18:48:21 +0000559Char *inet2name(struct vki_sockaddr_in *sa, UInt len, Char *name)
rjwalshf5f536f2003-11-17 17:45:00 +0000560{
nethercote73b526f2004-10-31 18:48:21 +0000561 if (sa == NULL || len == 0) {
rjwalshf5f536f2003-11-17 17:45:00 +0000562 VG_(sprintf)(name, "<unknown>");
563 } else {
tom329af4b2005-11-17 12:02:58 +0000564 UInt addr = VG_(ntohl)(sa->sin_addr.s_addr);
rjwalshf5f536f2003-11-17 17:45:00 +0000565 if (addr == 0) {
566 VG_(sprintf)(name, "<unbound>");
567 } else {
568 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
tom329af4b2005-11-17 12:02:58 +0000569 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
570 (addr>>8) & 0xFF, addr & 0xFF,
571 VG_(ntohs)(sa->sin_port));
rjwalshf5f536f2003-11-17 17:45:00 +0000572 }
573 }
574
575 return name;
576}
577
rjwalshf5f536f2003-11-17 17:45:00 +0000578/*
579 * Try get some details about a socket.
580 */
rjwalshf5f536f2003-11-17 17:45:00 +0000581static void
sewardj0a400c72005-07-23 09:22:46 +0000582getsockdetails(Int fd)
rjwalshf5f536f2003-11-17 17:45:00 +0000583{
584 union u {
nethercote73b526f2004-10-31 18:48:21 +0000585 struct vki_sockaddr a;
586 struct vki_sockaddr_in in;
587 struct vki_sockaddr_un un;
rjwalshf5f536f2003-11-17 17:45:00 +0000588 } laddr;
nethercote73b526f2004-10-31 18:48:21 +0000589 UInt llen;
rjwalshf5f536f2003-11-17 17:45:00 +0000590
591 llen = sizeof(laddr);
592 VG_(memset)(&laddr, 0, llen);
593
594 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
595 switch(laddr.a.sa_family) {
nethercote73b526f2004-10-31 18:48:21 +0000596 case VKI_AF_INET: {
rjwalshf5f536f2003-11-17 17:45:00 +0000597 static char lname[32];
598 static char pname[32];
nethercote73b526f2004-10-31 18:48:21 +0000599 struct vki_sockaddr_in paddr;
600 UInt plen = sizeof(struct vki_sockaddr_in);
rjwalshf5f536f2003-11-17 17:45:00 +0000601
602 if(VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
603 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s", fd,
604 inet2name(&(laddr.in), llen, lname),
605 inet2name(&paddr, plen, pname));
606 } else {
607 VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound",
608 fd, inet2name(&(laddr.in), llen, lname));
609 }
610 return;
611 }
nethercote73b526f2004-10-31 18:48:21 +0000612 case VKI_AF_UNIX: {
rjwalshf5f536f2003-11-17 17:45:00 +0000613 static char lname[256];
614 VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s", fd,
615 unix2name(&(laddr.un), llen, lname));
616 return;
617 }
618 default:
619 VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:",
620 laddr.a.sa_family, fd);
621 return;
622 }
623 }
624
625 VG_(message)(Vg_UserMsg, "Open socket %d:", fd);
626}
627
628
nethercote3a42fb82004-08-03 18:08:50 +0000629/* Dump out a summary, and a more detailed list, of open file descriptors. */
630void VG_(show_open_fds) ()
rjwalshf5f536f2003-11-17 17:45:00 +0000631{
632 OpenFd *i = allocated_fds;
633
nethercote3a42fb82004-08-03 18:08:50 +0000634 VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open at exit.", fd_count);
rjwalshf5f536f2003-11-17 17:45:00 +0000635
636 while(i) {
637 if(i->pathname) {
638 VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s", i->fd,
639 i->pathname);
640 } else {
sewardj0a400c72005-07-23 09:22:46 +0000641 Int val;
nethercote73b526f2004-10-31 18:48:21 +0000642 UInt len = sizeof(val);
rjwalshf5f536f2003-11-17 17:45:00 +0000643
nethercote73b526f2004-10-31 18:48:21 +0000644 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000645 VG_(message)(Vg_UserMsg, "Open file descriptor %d:", i->fd);
646 } else {
647 getsockdetails(i->fd);
648 }
649 }
650
651 if(i->where) {
652 VG_(pp_ExeContext)(i->where);
653 VG_(message)(Vg_UserMsg, "");
654 } else {
655 VG_(message)(Vg_UserMsg, " <inherited from parent>");
656 VG_(message)(Vg_UserMsg, "");
657 }
658
659 i = i->next;
660 }
661
662 VG_(message)(Vg_UserMsg, "");
663}
664
665/* If /proc/self/fd doesn't exist for some weird reason (like you've
666 got a kernel that doesn't have /proc support compiled in), then we
667 need to find out what file descriptors we inherited from our parent
668 process the hard way - by checking each fd in turn. */
669
670static
tom7c787822005-11-11 12:32:10 +0000671void do_hacky_preopened(void)
rjwalshf5f536f2003-11-17 17:45:00 +0000672{
673 struct vki_rlimit lim;
sewardj0a400c72005-07-23 09:22:46 +0000674 UInt count;
675 Int i;
rjwalshf5f536f2003-11-17 17:45:00 +0000676
nethercote620154f2004-11-12 21:21:07 +0000677 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
rjwalshf5f536f2003-11-17 17:45:00 +0000678 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
679 an arbitrarily high number. 1024 happens to be the limit in
680 the 2.4 kernels. */
681 count = 1024;
682 } else {
683 count = lim.rlim_cur;
684 }
685
686 for (i = 0; i < count; i++)
687 if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
njnf845f8f2005-06-23 02:26:47 +0000688 ML_(record_fd_open_nameless)(-1, i);
rjwalshf5f536f2003-11-17 17:45:00 +0000689}
690
691/* Initialize the list of open file descriptors with the file descriptors
692 we inherited from out parent process. */
693
694void VG_(init_preopened_fds)()
695{
sewardj0a400c72005-07-23 09:22:46 +0000696 Int ret;
rjwalshf5f536f2003-11-17 17:45:00 +0000697 struct vki_dirent d;
sewardj92645592005-07-23 09:18:34 +0000698 SysRes f;
rjwalshf5f536f2003-11-17 17:45:00 +0000699
700 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
sewardj92645592005-07-23 09:18:34 +0000701 if (f.isError) {
rjwalshf5f536f2003-11-17 17:45:00 +0000702 do_hacky_preopened();
703 return;
704 }
705
sewardj92645592005-07-23 09:18:34 +0000706 while ((ret = VG_(getdents)(f.val, &d, sizeof(d))) != 0) {
njnf845f8f2005-06-23 02:26:47 +0000707 if (ret == -1)
rjwalshf5f536f2003-11-17 17:45:00 +0000708 goto out;
709
njnf845f8f2005-06-23 02:26:47 +0000710 if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
sewardj0a400c72005-07-23 09:22:46 +0000711 Int fno = VG_(atoll)(d.d_name);
rjwalshf5f536f2003-11-17 17:45:00 +0000712
sewardj92645592005-07-23 09:18:34 +0000713 if (fno != f.val)
njnf845f8f2005-06-23 02:26:47 +0000714 if (VG_(clo_track_fds))
715 record_fd_open_named(-1, fno);
rjwalshf5f536f2003-11-17 17:45:00 +0000716 }
717
sewardj92645592005-07-23 09:18:34 +0000718 VG_(lseek)(f.val, d.d_off, VKI_SEEK_SET);
rjwalshf5f536f2003-11-17 17:45:00 +0000719 }
720
sewardj92645592005-07-23 09:18:34 +0000721 out:
722 VG_(close)(f.val);
rjwalshf5f536f2003-11-17 17:45:00 +0000723}
724
sewardjde4a1d02002-03-22 01:27:54 +0000725static
sewardj8c824512002-04-14 04:16:48 +0000726Char *strdupcat ( const Char *s1, const Char *s2, ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000727{
728 UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1;
njn25e49d8e72002-09-23 09:36:25 +0000729 Char *result = VG_(arena_malloc) ( aid, len );
sewardjde4a1d02002-03-22 01:27:54 +0000730 VG_(strcpy) ( result, s1 );
731 VG_(strcat) ( result, s2 );
732 return result;
733}
734
735static
tom56e1c842005-07-18 22:41:33 +0000736void pre_mem_read_sendmsg ( ThreadId tid, Bool read,
nethercote928a5f72004-11-03 18:10:37 +0000737 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000738{
njn9f46df62005-03-13 18:11:44 +0000739 Char *outmsg = strdupcat ( "socketcall.sendmsg", msg, VG_AR_CORE );
nethercoteef0c7662004-11-06 15:38:43 +0000740 PRE_MEM_READ( outmsg, base, size );
njn9f46df62005-03-13 18:11:44 +0000741 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000742}
743
744static
tom56e1c842005-07-18 22:41:33 +0000745void pre_mem_write_recvmsg ( ThreadId tid, Bool read,
nethercote928a5f72004-11-03 18:10:37 +0000746 Char *msg, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000747{
njn9f46df62005-03-13 18:11:44 +0000748 Char *outmsg = strdupcat ( "socketcall.recvmsg", msg, VG_AR_CORE );
tom56e1c842005-07-18 22:41:33 +0000749 if ( read )
750 PRE_MEM_READ( outmsg, base, size );
751 else
752 PRE_MEM_WRITE( outmsg, base, size );
njn9f46df62005-03-13 18:11:44 +0000753 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjde4a1d02002-03-22 01:27:54 +0000754}
755
756static
tom56e1c842005-07-18 22:41:33 +0000757void post_mem_write_recvmsg ( ThreadId tid, Bool read,
nethercote928a5f72004-11-03 18:10:37 +0000758 Char *fieldName, Addr base, SizeT size )
sewardjde4a1d02002-03-22 01:27:54 +0000759{
tom56e1c842005-07-18 22:41:33 +0000760 if ( !read )
761 POST_MEM_WRITE( base, size );
sewardjde4a1d02002-03-22 01:27:54 +0000762}
763
764static
sewardj8c824512002-04-14 04:16:48 +0000765void msghdr_foreachfield (
njn72718642003-07-24 08:45:32 +0000766 ThreadId tid,
nethercote73b526f2004-10-31 18:48:21 +0000767 struct vki_msghdr *msg,
tom56e1c842005-07-18 22:41:33 +0000768 void (*foreach_func)( ThreadId, Bool, Char *, Addr, SizeT )
sewardj8c824512002-04-14 04:16:48 +0000769 )
sewardjde4a1d02002-03-22 01:27:54 +0000770{
771 if ( !msg )
772 return;
773
tom56e1c842005-07-18 22:41:33 +0000774 foreach_func ( tid, True, "(msg)", (Addr)&msg->msg_name, sizeof( msg->msg_name ) );
775 foreach_func ( tid, True, "(msg)", (Addr)&msg->msg_namelen, sizeof( msg->msg_namelen ) );
776 foreach_func ( tid, True, "(msg)", (Addr)&msg->msg_iov, sizeof( msg->msg_iov ) );
777 foreach_func ( tid, True, "(msg)", (Addr)&msg->msg_iovlen, sizeof( msg->msg_iovlen ) );
778 foreach_func ( tid, True, "(msg)", (Addr)&msg->msg_control, sizeof( msg->msg_control ) );
779 foreach_func ( tid, True, "(msg)", (Addr)&msg->msg_controllen, sizeof( msg->msg_controllen ) );
tom621051e2006-03-24 16:48:19 +0000780 foreach_func ( tid, False, "(msg)", (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) );
sewardjde4a1d02002-03-22 01:27:54 +0000781
782 if ( msg->msg_name )
tom56e1c842005-07-18 22:41:33 +0000783 foreach_func ( tid, False,
sewardj8c824512002-04-14 04:16:48 +0000784 "(msg.msg_name)",
sewardjde4a1d02002-03-22 01:27:54 +0000785 (Addr)msg->msg_name, msg->msg_namelen );
786
787 if ( msg->msg_iov ) {
nethercote73b526f2004-10-31 18:48:21 +0000788 struct vki_iovec *iov = msg->msg_iov;
sewardjde4a1d02002-03-22 01:27:54 +0000789 UInt i;
790
tom56e1c842005-07-18 22:41:33 +0000791 foreach_func ( tid, True,
sewardj8c824512002-04-14 04:16:48 +0000792 "(msg.msg_iov)",
nethercote73b526f2004-10-31 18:48:21 +0000793 (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) );
sewardjde4a1d02002-03-22 01:27:54 +0000794
795 for ( i = 0; i < msg->msg_iovlen; ++i, ++iov )
tom56e1c842005-07-18 22:41:33 +0000796 foreach_func ( tid, False,
tom621051e2006-03-24 16:48:19 +0000797 "(msg.msg_iov[i])",
sewardjde4a1d02002-03-22 01:27:54 +0000798 (Addr)iov->iov_base, iov->iov_len );
799 }
800
801 if ( msg->msg_control )
tom56e1c842005-07-18 22:41:33 +0000802 foreach_func ( tid, False,
sewardj8c824512002-04-14 04:16:48 +0000803 "(msg.msg_control)",
sewardjde4a1d02002-03-22 01:27:54 +0000804 (Addr)msg->msg_control, msg->msg_controllen );
805}
806
sewardjb5f6f512005-03-10 23:59:00 +0000807static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
rjwalshf5f536f2003-11-17 17:45:00 +0000808{
nethercote73b526f2004-10-31 18:48:21 +0000809 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
rjwalshf5f536f2003-11-17 17:45:00 +0000810
811 while (cm) {
nethercote73b526f2004-10-31 18:48:21 +0000812 if (cm->cmsg_level == VKI_SOL_SOCKET &&
813 cm->cmsg_type == VKI_SCM_RIGHTS ) {
sewardj0a400c72005-07-23 09:22:46 +0000814 Int *fds = (Int *) VKI_CMSG_DATA(cm);
815 Int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
rjwalshf5f536f2003-11-17 17:45:00 +0000816 / sizeof(int);
sewardj0a400c72005-07-23 09:22:46 +0000817 Int i;
rjwalshf5f536f2003-11-17 17:45:00 +0000818
819 for (i = 0; i < fdc; i++)
820 if(VG_(clo_track_fds))
nethercote493dd182004-02-24 23:57:47 +0000821 // XXX: must we check the range on these fds with
cerion7b2c38c2005-06-23 07:52:54 +0000822 // ML_(fd_allowed)()?
njnf845f8f2005-06-23 02:26:47 +0000823 record_fd_open_named(tid, fds[i]);
rjwalshf5f536f2003-11-17 17:45:00 +0000824 }
825
nethercote73b526f2004-10-31 18:48:21 +0000826 cm = VKI_CMSG_NXTHDR(msg, cm);
rjwalshf5f536f2003-11-17 17:45:00 +0000827 }
828}
829
sewardjc483e8f2002-05-03 21:01:35 +0000830static
jsgf855d93d2003-10-13 22:26:55 +0000831void pre_mem_read_sockaddr ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +0000832 Char *description,
833 struct vki_sockaddr *sa, UInt salen )
sewardjc483e8f2002-05-03 21:01:35 +0000834{
sewardjff7c1ab2003-02-24 21:55:34 +0000835 Char *outmsg;
836
837 /* NULL/zero-length sockaddrs are legal */
838 if ( sa == NULL || salen == 0 ) return;
839
njn9f46df62005-03-13 18:11:44 +0000840 outmsg = VG_(arena_malloc) ( VG_AR_CORE,
nethercote73b526f2004-10-31 18:48:21 +0000841 VG_(strlen)( description ) + 30 );
sewardjc483e8f2002-05-03 21:01:35 +0000842
843 VG_(sprintf) ( outmsg, description, ".sa_family" );
nethercoteef0c7662004-11-06 15:38:43 +0000844 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
jsgf855d93d2003-10-13 22:26:55 +0000845
sewardjc483e8f2002-05-03 21:01:35 +0000846 switch (sa->sa_family) {
847
nethercote73b526f2004-10-31 18:48:21 +0000848 case VKI_AF_UNIX:
sewardjc483e8f2002-05-03 21:01:35 +0000849 VG_(sprintf) ( outmsg, description, ".sun_path" );
nethercoteef0c7662004-11-06 15:38:43 +0000850 PRE_MEM_RASCIIZ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000851 (Addr) ((struct vki_sockaddr_un *) sa)->sun_path);
sewardjc483e8f2002-05-03 21:01:35 +0000852 break;
853
nethercote73b526f2004-10-31 18:48:21 +0000854 case VKI_AF_INET:
sewardjc483e8f2002-05-03 21:01:35 +0000855 VG_(sprintf) ( outmsg, description, ".sin_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000856 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000857 (Addr) &((struct vki_sockaddr_in *) sa)->sin_port,
858 sizeof (((struct vki_sockaddr_in *) sa)->sin_port));
sewardjc483e8f2002-05-03 21:01:35 +0000859 VG_(sprintf) ( outmsg, description, ".sin_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000860 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000861 (Addr) &((struct vki_sockaddr_in *) sa)->sin_addr,
862 sizeof (struct vki_in_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000863 break;
864
nethercote73b526f2004-10-31 18:48:21 +0000865 case VKI_AF_INET6:
sewardjc483e8f2002-05-03 21:01:35 +0000866 VG_(sprintf) ( outmsg, description, ".sin6_port" );
nethercoteef0c7662004-11-06 15:38:43 +0000867 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000868 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_port,
869 sizeof (((struct vki_sockaddr_in6 *) sa)->sin6_port));
sewardjc483e8f2002-05-03 21:01:35 +0000870 VG_(sprintf) ( outmsg, description, ".sin6_flowinfo" );
nethercoteef0c7662004-11-06 15:38:43 +0000871 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000872 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_flowinfo,
873 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000874 VG_(sprintf) ( outmsg, description, ".sin6_addr" );
nethercoteef0c7662004-11-06 15:38:43 +0000875 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000876 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_addr,
877 sizeof (struct vki_in6_addr));
sewardjc483e8f2002-05-03 21:01:35 +0000878 VG_(sprintf) ( outmsg, description, ".sin6_scope_id" );
nethercoteef0c7662004-11-06 15:38:43 +0000879 PRE_MEM_READ( outmsg,
nethercote73b526f2004-10-31 18:48:21 +0000880 (Addr) &((struct vki_sockaddr_in6 *) sa)->sin6_scope_id,
881 sizeof (__vki_u32));
sewardjc483e8f2002-05-03 21:01:35 +0000882 break;
883
884 default:
885 VG_(sprintf) ( outmsg, description, "" );
nethercoteef0c7662004-11-06 15:38:43 +0000886 PRE_MEM_READ( outmsg, (Addr) sa, salen );
sewardjc483e8f2002-05-03 21:01:35 +0000887 break;
888 }
889
njn9f46df62005-03-13 18:11:44 +0000890 VG_(arena_free) ( VG_AR_CORE, outmsg );
sewardjc483e8f2002-05-03 21:01:35 +0000891}
892
njn25e49d8e72002-09-23 09:36:25 +0000893/* Dereference a pointer to a UInt. */
njn72718642003-07-24 08:45:32 +0000894static UInt deref_UInt ( ThreadId tid, Addr a, Char* s )
njn25e49d8e72002-09-23 09:36:25 +0000895{
896 UInt* a_p = (UInt*)a;
nethercoteef0c7662004-11-06 15:38:43 +0000897 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
njn25e49d8e72002-09-23 09:36:25 +0000898 if (a_p == NULL)
899 return 0;
900 else
901 return *a_p;
902}
903
njn25e49d8e72002-09-23 09:36:25 +0000904static
njn72718642003-07-24 08:45:32 +0000905void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p,
njn25e49d8e72002-09-23 09:36:25 +0000906 Char* buf_s, Char* buflen_s )
907{
njn51d827b2005-05-09 01:02:08 +0000908 if (VG_(tdict).track_pre_mem_write) {
njn72718642003-07-24 08:45:32 +0000909 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
njn25e49d8e72002-09-23 09:36:25 +0000910 if (buflen_in > 0) {
njn51d827b2005-05-09 01:02:08 +0000911 VG_(tdict).track_pre_mem_write( Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
njn25e49d8e72002-09-23 09:36:25 +0000912 }
913 }
914}
915
916static
sewardja8d8e232005-06-07 20:04:56 +0000917void buf_and_len_post_check( ThreadId tid, SysRes res,
njn25e49d8e72002-09-23 09:36:25 +0000918 Addr buf_p, Addr buflen_p, Char* s )
919{
sewardja8d8e232005-06-07 20:04:56 +0000920 if (!res.isError && VG_(tdict).track_post_mem_write) {
njn72718642003-07-24 08:45:32 +0000921 UInt buflen_out = deref_UInt( tid, buflen_p, s);
njn25e49d8e72002-09-23 09:36:25 +0000922 if (buflen_out > 0 && buf_p != (Addr)NULL) {
njn51d827b2005-05-09 01:02:08 +0000923 VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
njn25e49d8e72002-09-23 09:36:25 +0000924 }
925 }
926}
927
928/* ---------------------------------------------------------------------
929 Data seg end, for brk()
930 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +0000931
sewardj45f4e7c2005-09-27 19:20:21 +0000932/* +--------+------------+
933 | anon | resvn |
934 +--------+------------+
nethercotece471262004-08-25 13:43:44 +0000935
sewardj45f4e7c2005-09-27 19:20:21 +0000936 ^ ^ ^
937 | | boundary is page aligned
938 | VG_(brk_limit) -- no alignment constraint
939 VG_(brk_base) -- page aligned -- does not move
940
941 Both the anon part and the reservation part are always at least
942 one page.
943*/
944
945/* Set the new data segment end to NEWBRK. If this succeeds, return
946 NEWBRK, else return the current data segment end. */
947
948static Addr do_brk ( Addr newbrk )
949{
950 NSegment *aseg, *rseg;
951 Addr newbrkP;
952 SizeT delta;
953 Bool ok;
954 Bool debug = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000955
956 if (debug)
sewardj548be6d2005-02-16 01:31:37 +0000957 VG_(printf)("\ndo_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
fitzhardinge98abfc72003-12-16 02:05:15 +0000958 VG_(brk_base), VG_(brk_limit), newbrk);
959
sewardj79048ce2005-02-18 08:28:32 +0000960# if 0
sewardje517b802005-02-16 01:58:51 +0000961 if (0) show_segments("in_brk");
sewardj79048ce2005-02-18 08:28:32 +0000962# endif
sewardj548be6d2005-02-16 01:31:37 +0000963
sewardj45f4e7c2005-09-27 19:20:21 +0000964 if (newbrk < VG_(brk_base))
965 /* Clearly impossible. */
966 goto bad;
fitzhardinge98abfc72003-12-16 02:05:15 +0000967
sewardj45f4e7c2005-09-27 19:20:21 +0000968 if (newbrk >= VG_(brk_base) && newbrk < VG_(brk_limit)) {
969 /* shrinking the data segment. Be lazy and don't munmap the
970 excess area. */
971 NSegment* seg = VG_(am_find_nsegment)(newbrk);
972 if (seg && seg->hasT)
973 VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk,
974 "do_brk(shrink)" );
sewardjd2d241b2006-02-14 11:37:41 +0000975 /* Since we're being lazy and not unmapping pages, we have to
976 zero out the area, so that if the area later comes back into
977 circulation, it will be filled with zeroes, as if it really
978 had been unmapped and later remapped. Be a bit paranoid and
979 try hard to ensure we're not going to segfault by doing the
980 write - check both ends of the range are in the same segment
981 and that segment is writable. */
982 if (seg) {
983 /* pre: newbrk < VG_(brk_limit)
984 => newbrk <= VG_(brk_limit)-1 */
985 NSegment* seg2;
986 vg_assert(newbrk < VG_(brk_limit));
987 seg2 = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
988 if (seg2 && seg == seg2 && seg->hasW)
989 VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk );
990 }
991
sewardj45f4e7c2005-09-27 19:20:21 +0000992 VG_(brk_limit) = newbrk;
993 return newbrk;
994 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000995
sewardj45f4e7c2005-09-27 19:20:21 +0000996 /* otherwise we're expanding the brk segment. */
tom8e5963d2005-10-06 14:49:21 +0000997 if (VG_(brk_limit) > VG_(brk_base))
998 aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
999 else
1000 aseg = VG_(am_find_nsegment)( VG_(brk_limit) );
sewardj45f4e7c2005-09-27 19:20:21 +00001001 rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
fitzhardinge98abfc72003-12-16 02:05:15 +00001002
sewardj45f4e7c2005-09-27 19:20:21 +00001003 /* These should be assured by setup_client_dataseg in m_main. */
1004 vg_assert(aseg);
1005 vg_assert(rseg);
1006 vg_assert(aseg->kind == SkAnonC);
1007 vg_assert(rseg->kind == SkResvn);
1008 vg_assert(aseg->end+1 == rseg->start);
fitzhardinge98abfc72003-12-16 02:05:15 +00001009
sewardj45f4e7c2005-09-27 19:20:21 +00001010 vg_assert(newbrk >= VG_(brk_base));
1011 if (newbrk <= rseg->start) {
1012 /* still fits within the anon segment. */
1013 VG_(brk_limit) = newbrk;
1014 return newbrk;
1015 }
fitzhardinge98abfc72003-12-16 02:05:15 +00001016
tom02f75332006-06-21 08:01:14 +00001017 if (newbrk > rseg->end+1 - VKI_PAGE_SIZE) {
sewardj45f4e7c2005-09-27 19:20:21 +00001018 /* request is too large -- the resvn would fall below 1 page,
1019 which isn't allowed. */
1020 goto bad;
1021 }
fitzhardinge98abfc72003-12-16 02:05:15 +00001022
sewardj45f4e7c2005-09-27 19:20:21 +00001023 newbrkP = VG_PGROUNDUP(newbrk);
tom02f75332006-06-21 08:01:14 +00001024 vg_assert(newbrkP > rseg->start && newbrkP <= rseg->end+1 - VKI_PAGE_SIZE);
sewardj45f4e7c2005-09-27 19:20:21 +00001025 delta = newbrkP - rseg->start;
1026 vg_assert(delta > 0);
1027 vg_assert(VG_IS_PAGE_ALIGNED(delta));
1028
1029 ok = VG_(am_extend_into_adjacent_reservation_client)( aseg, delta );
1030 if (!ok) goto bad;
fitzhardinge98abfc72003-12-16 02:05:15 +00001031
sewardj45f4e7c2005-09-27 19:20:21 +00001032 VG_(brk_limit) = newbrk;
1033 return newbrk;
fitzhardinge98abfc72003-12-16 02:05:15 +00001034
sewardj45f4e7c2005-09-27 19:20:21 +00001035 bad:
1036 return VG_(brk_limit);
fitzhardinge98abfc72003-12-16 02:05:15 +00001037}
1038
1039
njn25e49d8e72002-09-23 09:36:25 +00001040/* ---------------------------------------------------------------------
jsgf855d93d2003-10-13 22:26:55 +00001041 Vet file descriptors for sanity
1042 ------------------------------------------------------------------ */
sewardj04236902005-10-04 22:27:22 +00001043/*
1044> - what does the "Bool soft" parameter mean?
1045
1046(Tom Hughes, 3 Oct 05):
1047
1048Whether or not to consider a file descriptor invalid if it is above
1049the current soft limit.
1050
1051Basically if we are testing whether a newly created file descriptor is
1052valid (in a post handler) then we set soft to true, and if we are
1053testing whether a file descriptor that is about to be used (in a pre
1054handler) is valid [viz, an already-existing fd] then we set it to false.
1055
1056The point is that if the (virtual) soft limit is lowered then any
1057existing descriptors can still be read/written/closed etc (so long as
1058they are below the valgrind reserved descriptors) but no new
1059descriptors can be created above the new soft limit.
1060
1061(jrs 4 Oct 05: in which case, I've renamed it "isNewFd")
1062*/
jsgf855d93d2003-10-13 22:26:55 +00001063
1064/* Return true if we're allowed to use or create this fd */
sewardj04236902005-10-04 22:27:22 +00001065Bool ML_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool isNewFd)
jsgf855d93d2003-10-13 22:26:55 +00001066{
sewardj04236902005-10-04 22:27:22 +00001067 Bool allowed = True;
1068
1069 /* hard limits always apply */
1070 if (fd < 0 || fd >= VG_(fd_hard_limit))
1071 allowed = False;
1072
1073 /* hijacking the logging fd is never allowed */
1074 if (fd == VG_(clo_log_fd))
1075 allowed = False;
1076
1077 /* if creating a new fd (rather than using an existing one), the
1078 soft limit must also be observed */
1079 if (isNewFd && fd >= VG_(fd_soft_limit))
1080 allowed = False;
1081
1082 /* this looks like it ought to be included, but causes problems: */
1083 /*
1084 if (fd == 2 && VG_(debugLog_getLevel)() > 0)
1085 allowed = False;
1086 */
1087 /* The difficulty is as follows: consider a program P which expects
1088 to be able to mess with (redirect) its own stderr (fd 2).
1089 Usually to deal with P we would issue command line flags to send
1090 logging somewhere other than stderr, so as not to disrupt P.
1091 The problem is that -d unilaterally hijacks stderr with no
1092 consultation with P. And so, if this check is enabled, P will
1093 work OK normally but fail if -d is issued.
1094
1095 Basically -d is a hack and you take your chances when using it.
1096 It's very useful for low level debugging -- particularly at
1097 startup -- and having its presence change the behaviour of the
1098 client is exactly what we don't want. */
1099
1100 /* croak? */
1101 if ((!allowed) && VG_(showing_core_errors)() ) {
jsewardd9320a42003-12-12 06:40:05 +00001102 VG_(message)(Vg_UserMsg,
1103 "Warning: invalid file descriptor %d in syscall %s()",
nethercote1543adf2004-10-25 15:43:21 +00001104 fd, syscallname);
nethercotef8548672004-06-21 12:42:35 +00001105 if (fd == VG_(clo_log_fd))
jsewardd9320a42003-12-12 06:40:05 +00001106 VG_(message)(Vg_UserMsg,
nethercotef8548672004-06-21 12:42:35 +00001107 " Use --log-fd=<number> to select an alternative log fd.");
jsgf855d93d2003-10-13 22:26:55 +00001108 if (VG_(clo_verbosity) > 1) {
njnd01fef72005-03-25 23:35:48 +00001109 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
jsgf855d93d2003-10-13 22:26:55 +00001110 }
jsgf855d93d2003-10-13 22:26:55 +00001111 }
sewardj04236902005-10-04 22:27:22 +00001112
1113 return allowed;
jsgf855d93d2003-10-13 22:26:55 +00001114}
1115
1116
1117/* ---------------------------------------------------------------------
sewardj9efbbef2005-03-01 16:45:23 +00001118 Deal with a bunch of socket-related syscalls
1119 ------------------------------------------------------------------ */
1120
1121/* ------ */
1122
sewardj987a8eb2005-03-01 19:00:30 +00001123void
sewardj7eb7c582005-06-23 01:02:53 +00001124ML_(generic_PRE_sys_socketpair) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001125 UWord arg0, UWord arg1,
1126 UWord arg2, UWord arg3 )
1127{
1128 /* int socketpair(int d, int type, int protocol, int sv[2]); */
1129 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
1130 arg3, 2*sizeof(int) );
1131}
1132
sewardja8d8e232005-06-07 20:04:56 +00001133SysRes
sewardj7eb7c582005-06-23 01:02:53 +00001134ML_(generic_POST_sys_socketpair) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001135 SysRes res,
sewardj987a8eb2005-03-01 19:00:30 +00001136 UWord arg0, UWord arg1,
1137 UWord arg2, UWord arg3 )
sewardj9efbbef2005-03-01 16:45:23 +00001138{
sewardja8d8e232005-06-07 20:04:56 +00001139 SysRes r = res;
sewardj9efbbef2005-03-01 16:45:23 +00001140 Int fd1 = ((Int*)arg3)[0];
1141 Int fd2 = ((Int*)arg3)[1];
tom60a4b0b2005-10-12 10:45:27 +00001142 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001143 POST_MEM_WRITE( arg3, 2*sizeof(int) );
sewardj7eb7c582005-06-23 01:02:53 +00001144 if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
1145 !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
sewardj9efbbef2005-03-01 16:45:23 +00001146 VG_(close)(fd1);
1147 VG_(close)(fd2);
sewardja8d8e232005-06-07 20:04:56 +00001148 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +00001149 } else {
1150 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1151 if (VG_(clo_track_fds)) {
njnf845f8f2005-06-23 02:26:47 +00001152 ML_(record_fd_open_nameless)(tid, fd1);
1153 ML_(record_fd_open_nameless)(tid, fd2);
sewardj9efbbef2005-03-01 16:45:23 +00001154 }
1155 }
1156 return r;
1157}
1158
1159/* ------ */
1160
sewardja8d8e232005-06-07 20:04:56 +00001161SysRes
sewardj7eb7c582005-06-23 01:02:53 +00001162ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
sewardj9efbbef2005-03-01 16:45:23 +00001163{
sewardja8d8e232005-06-07 20:04:56 +00001164 SysRes r = res;
1165 vg_assert(!res.isError); /* guaranteed by caller */
sewardj7eb7c582005-06-23 01:02:53 +00001166 if (!ML_(fd_allowed)(res.val, "socket", tid, True)) {
sewardja8d8e232005-06-07 20:04:56 +00001167 VG_(close)(res.val);
1168 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +00001169 } else {
1170 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00001171 ML_(record_fd_open_nameless)(tid, res.val);
sewardj9efbbef2005-03-01 16:45:23 +00001172 }
1173 return r;
1174}
1175
1176/* ------ */
1177
sewardj987a8eb2005-03-01 19:00:30 +00001178void
sewardj7eb7c582005-06-23 01:02:53 +00001179ML_(generic_PRE_sys_bind) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001180 UWord arg0, UWord arg1, UWord arg2 )
1181{
1182 /* int bind(int sockfd, struct sockaddr *my_addr,
1183 int addrlen); */
1184 pre_mem_read_sockaddr(
1185 tid, "socketcall.bind(my_addr.%s)",
1186 (struct vki_sockaddr *) arg1, arg2
1187 );
1188}
1189
1190/* ------ */
1191
sewardj987a8eb2005-03-01 19:00:30 +00001192void
sewardj7eb7c582005-06-23 01:02:53 +00001193ML_(generic_PRE_sys_accept) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001194 UWord arg0, UWord arg1, UWord arg2 )
1195{
1196 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1197 Addr addr_p = arg1;
1198 Addr addrlen_p = arg2;
1199 if (addr_p != (Addr)NULL)
1200 buf_and_len_pre_check ( tid, addr_p, addrlen_p,
1201 "socketcall.accept(addr)",
1202 "socketcall.accept(addrlen_in)" );
1203}
1204
sewardja8d8e232005-06-07 20:04:56 +00001205SysRes
sewardj7eb7c582005-06-23 01:02:53 +00001206ML_(generic_POST_sys_accept) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001207 SysRes res,
sewardj987a8eb2005-03-01 19:00:30 +00001208 UWord arg0, UWord arg1, UWord arg2 )
sewardj9efbbef2005-03-01 16:45:23 +00001209{
sewardja8d8e232005-06-07 20:04:56 +00001210 SysRes r = res;
1211 vg_assert(!res.isError); /* guaranteed by caller */
sewardj7eb7c582005-06-23 01:02:53 +00001212 if (!ML_(fd_allowed)(res.val, "accept", tid, True)) {
sewardja8d8e232005-06-07 20:04:56 +00001213 VG_(close)(res.val);
1214 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
sewardj9efbbef2005-03-01 16:45:23 +00001215 } else {
1216 Addr addr_p = arg1;
1217 Addr addrlen_p = arg2;
1218 if (addr_p != (Addr)NULL)
1219 buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
1220 "socketcall.accept(addrlen_out)" );
1221 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00001222 ML_(record_fd_open_nameless)(tid, res.val);
sewardj9efbbef2005-03-01 16:45:23 +00001223 }
1224 return r;
1225}
1226
1227/* ------ */
1228
sewardj987a8eb2005-03-01 19:00:30 +00001229void
sewardj7eb7c582005-06-23 01:02:53 +00001230ML_(generic_PRE_sys_sendto) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001231 UWord arg0, UWord arg1, UWord arg2,
1232 UWord arg3, UWord arg4, UWord arg5 )
1233{
1234 /* int sendto(int s, const void *msg, int len,
1235 unsigned int flags,
1236 const struct sockaddr *to, int tolen); */
1237 PRE_MEM_READ( "socketcall.sendto(msg)",
1238 arg1, /* msg */
1239 arg2 /* len */ );
1240 pre_mem_read_sockaddr(
1241 tid, "socketcall.sendto(to.%s)",
1242 (struct vki_sockaddr *) arg4, arg5
1243 );
1244}
1245
1246/* ------ */
1247
sewardj987a8eb2005-03-01 19:00:30 +00001248void
sewardj7eb7c582005-06-23 01:02:53 +00001249ML_(generic_PRE_sys_send) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001250 UWord arg0, UWord arg1, UWord arg2 )
1251{
1252 /* int send(int s, const void *msg, size_t len, int flags); */
1253 PRE_MEM_READ( "socketcall.send(msg)",
1254 arg1, /* msg */
1255 arg2 /* len */ );
1256
1257}
1258
1259/* ------ */
1260
sewardj987a8eb2005-03-01 19:00:30 +00001261void
sewardj7eb7c582005-06-23 01:02:53 +00001262ML_(generic_PRE_sys_recvfrom) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001263 UWord arg0, UWord arg1, UWord arg2,
1264 UWord arg3, UWord arg4, UWord arg5 )
1265{
1266 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1267 struct sockaddr *from, int *fromlen); */
1268 Addr buf_p = arg1;
1269 Int len = arg2;
1270 Addr from_p = arg4;
1271 Addr fromlen_p = arg5;
1272 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1273 if (from_p != (Addr)NULL)
1274 buf_and_len_pre_check ( tid, from_p, fromlen_p,
1275 "socketcall.recvfrom(from)",
1276 "socketcall.recvfrom(fromlen_in)" );
1277}
1278
sewardj987a8eb2005-03-01 19:00:30 +00001279void
sewardj7eb7c582005-06-23 01:02:53 +00001280ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001281 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001282 UWord arg0, UWord arg1, UWord arg2,
1283 UWord arg3, UWord arg4, UWord arg5 )
1284{
1285 Addr buf_p = arg1;
1286 Int len = arg2;
1287 Addr from_p = arg4;
1288 Addr fromlen_p = arg5;
1289
sewardja8d8e232005-06-07 20:04:56 +00001290 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001291 if (from_p != (Addr)NULL)
1292 buf_and_len_post_check ( tid, res, from_p, fromlen_p,
1293 "socketcall.recvfrom(fromlen_out)" );
1294 POST_MEM_WRITE( buf_p, len );
1295}
1296
1297/* ------ */
1298
sewardj987a8eb2005-03-01 19:00:30 +00001299void
sewardj7eb7c582005-06-23 01:02:53 +00001300ML_(generic_PRE_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001301 UWord arg0, UWord arg1, UWord arg2 )
1302{
1303 /* int recv(int s, void *buf, int len, unsigned int flags); */
1304 /* man 2 recv says:
1305 The recv call is normally used only on a connected socket
1306 (see connect(2)) and is identical to recvfrom with a NULL
1307 from parameter.
1308 */
1309 PRE_MEM_WRITE( "socketcall.recv(buf)",
1310 arg1, /* buf */
1311 arg2 /* len */ );
1312}
1313
sewardj987a8eb2005-03-01 19:00:30 +00001314void
sewardj7eb7c582005-06-23 01:02:53 +00001315ML_(generic_POST_sys_recv) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001316 UWord res,
1317 UWord arg0, UWord arg1, UWord arg2 )
1318{
1319 if (res >= 0 && arg1 != 0) {
1320 POST_MEM_WRITE( arg1, /* buf */
1321 arg2 /* len */ );
1322 }
1323}
1324
1325/* ------ */
1326
sewardj987a8eb2005-03-01 19:00:30 +00001327void
sewardj7eb7c582005-06-23 01:02:53 +00001328ML_(generic_PRE_sys_connect) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001329 UWord arg0, UWord arg1, UWord arg2 )
1330{
1331 /* int connect(int sockfd,
1332 struct sockaddr *serv_addr, int addrlen ); */
1333 PRE_MEM_READ( "socketcall.connect(serv_addr.sa_family)",
1334 arg1, /* serv_addr */
1335 sizeof(vki_sa_family_t));
1336 pre_mem_read_sockaddr( tid,
1337 "socketcall.connect(serv_addr.%s)",
1338 (struct vki_sockaddr *) arg1, arg2);
1339}
1340
1341/* ------ */
1342
sewardj987a8eb2005-03-01 19:00:30 +00001343void
sewardj7eb7c582005-06-23 01:02:53 +00001344ML_(generic_PRE_sys_setsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001345 UWord arg0, UWord arg1, UWord arg2,
1346 UWord arg3, UWord arg4 )
1347{
1348 /* int setsockopt(int s, int level, int optname,
1349 const void *optval, int optlen); */
1350 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1351 arg3, /* optval */
1352 arg4 /* optlen */ );
1353}
1354
1355/* ------ */
1356
sewardj987a8eb2005-03-01 19:00:30 +00001357void
sewardj7eb7c582005-06-23 01:02:53 +00001358ML_(generic_PRE_sys_getsockopt) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001359 UWord arg0, UWord arg1, UWord arg2,
1360 UWord arg3, UWord arg4 )
1361{
1362 /* int getsockopt(int s, int level, int optname,
1363 void *optval, socklen_t *optlen); */
1364 Addr optval_p = arg3;
1365 Addr optlen_p = arg4;
1366 /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */
tom1aa57372005-08-28 10:16:29 +00001367 if (optval_p != (Addr)NULL) {
sewardj9efbbef2005-03-01 16:45:23 +00001368 buf_and_len_pre_check ( tid, optval_p, optlen_p,
1369 "socketcall.getsockopt(optval)",
1370 "socketcall.getsockopt(optlen)" );
tom1aa57372005-08-28 10:16:29 +00001371 if (arg1 == VKI_SOL_SCTP &&
1372 (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) {
1373 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
1374 int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num;
1375 PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)", (Addr)ga->addrs, address_bytes );
1376 }
1377 }
sewardj9efbbef2005-03-01 16:45:23 +00001378}
1379
sewardj987a8eb2005-03-01 19:00:30 +00001380void
sewardj7eb7c582005-06-23 01:02:53 +00001381ML_(generic_POST_sys_getsockopt) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001382 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001383 UWord arg0, UWord arg1, UWord arg2,
1384 UWord arg3, UWord arg4 )
1385{
1386 Addr optval_p = arg3;
1387 Addr optlen_p = arg4;
sewardja8d8e232005-06-07 20:04:56 +00001388 vg_assert(!res.isError); /* guaranteed by caller */
tom1aa57372005-08-28 10:16:29 +00001389 if (optval_p != (Addr)NULL) {
sewardj9efbbef2005-03-01 16:45:23 +00001390 buf_and_len_post_check ( tid, res, optval_p, optlen_p,
1391 "socketcall.getsockopt(optlen_out)" );
tom1aa57372005-08-28 10:16:29 +00001392 if (arg1 == VKI_SOL_SCTP &&
1393 (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) {
1394 struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3;
1395 struct vki_sockaddr *a = ga->addrs;
1396 int i;
1397 for (i = 0; i < ga->addr_num; i++) {
1398 int sl = 0;
1399 if (a->sa_family == VKI_AF_INET)
1400 sl = sizeof(struct vki_sockaddr_in);
1401 else if (a->sa_family == VKI_AF_INET6)
1402 sl = sizeof(struct vki_sockaddr_in6);
1403 else {
1404 VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled address type %d", a->sa_family);
1405 }
1406 a = (struct vki_sockaddr*)((char*)a + sl);
1407 }
1408 POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs );
1409 }
1410 }
sewardj9efbbef2005-03-01 16:45:23 +00001411}
1412
1413/* ------ */
1414
sewardj987a8eb2005-03-01 19:00:30 +00001415void
sewardj7eb7c582005-06-23 01:02:53 +00001416ML_(generic_PRE_sys_getsockname) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001417 UWord arg0, UWord arg1, UWord arg2 )
1418{
1419 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1420 Addr name_p = arg1;
1421 Addr namelen_p = arg2;
1422 /* Nb: name_p cannot be NULL */
1423 buf_and_len_pre_check ( tid, name_p, namelen_p,
1424 "socketcall.getsockname(name)",
1425 "socketcall.getsockname(namelen_in)" );
1426}
1427
sewardj987a8eb2005-03-01 19:00:30 +00001428void
sewardj7eb7c582005-06-23 01:02:53 +00001429ML_(generic_POST_sys_getsockname) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001430 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001431 UWord arg0, UWord arg1, UWord arg2 )
1432{
1433 Addr name_p = arg1;
1434 Addr namelen_p = arg2;
sewardja8d8e232005-06-07 20:04:56 +00001435 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001436 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1437 "socketcall.getsockname(namelen_out)" );
1438}
1439
1440/* ------ */
1441
sewardj987a8eb2005-03-01 19:00:30 +00001442void
sewardj7eb7c582005-06-23 01:02:53 +00001443ML_(generic_PRE_sys_getpeername) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001444 UWord arg0, UWord arg1, UWord arg2 )
1445{
1446 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1447 Addr name_p = arg1;
1448 Addr namelen_p = arg2;
1449 /* Nb: name_p cannot be NULL */
1450 buf_and_len_pre_check ( tid, name_p, namelen_p,
1451 "socketcall.getpeername(name)",
1452 "socketcall.getpeername(namelen_in)" );
1453}
1454
sewardj987a8eb2005-03-01 19:00:30 +00001455void
sewardj7eb7c582005-06-23 01:02:53 +00001456ML_(generic_POST_sys_getpeername) ( ThreadId tid,
sewardja8d8e232005-06-07 20:04:56 +00001457 SysRes res,
sewardj9efbbef2005-03-01 16:45:23 +00001458 UWord arg0, UWord arg1, UWord arg2 )
1459{
1460 Addr name_p = arg1;
1461 Addr namelen_p = arg2;
sewardja8d8e232005-06-07 20:04:56 +00001462 vg_assert(!res.isError); /* guaranteed by caller */
sewardj9efbbef2005-03-01 16:45:23 +00001463 buf_and_len_post_check ( tid, res, name_p, namelen_p,
1464 "socketcall.getpeername(namelen_out)" );
1465}
1466
1467/* ------ */
1468
sewardj987a8eb2005-03-01 19:00:30 +00001469void
sewardj7eb7c582005-06-23 01:02:53 +00001470ML_(generic_PRE_sys_sendmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001471 UWord arg0, UWord arg1 )
1472{
1473 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1474 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1475 msghdr_foreachfield ( tid, msg, pre_mem_read_sendmsg );
1476}
1477
1478/* ------ */
1479
sewardj987a8eb2005-03-01 19:00:30 +00001480void
sewardj7eb7c582005-06-23 01:02:53 +00001481ML_(generic_PRE_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001482 UWord arg0, UWord arg1 )
1483{
1484 /* int recvmsg(int s, struct msghdr *msg, int flags); */
1485 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1486 msghdr_foreachfield ( tid, msg, pre_mem_write_recvmsg );
1487}
1488
sewardj987a8eb2005-03-01 19:00:30 +00001489void
sewardj7eb7c582005-06-23 01:02:53 +00001490ML_(generic_POST_sys_recvmsg) ( ThreadId tid,
sewardj9efbbef2005-03-01 16:45:23 +00001491 UWord arg0, UWord arg1 )
1492{
1493 struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
1494 msghdr_foreachfield( tid, msg, post_mem_write_recvmsg );
1495 check_cmsg_for_fds( tid, msg );
1496}
1497
1498
1499/* ---------------------------------------------------------------------
sewardjb369c5e2005-03-24 17:52:02 +00001500 Deal with a bunch of IPC related syscalls
1501 ------------------------------------------------------------------ */
1502
1503/* ------ */
1504
1505void
sewardj7eb7c582005-06-23 01:02:53 +00001506ML_(generic_PRE_sys_semop) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001507 UWord arg0, UWord arg1, UWord arg2 )
1508{
1509 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1510 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1511}
1512
1513/* ------ */
1514
1515void
sewardj7eb7c582005-06-23 01:02:53 +00001516ML_(generic_PRE_sys_semtimedop) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001517 UWord arg0, UWord arg1,
1518 UWord arg2, UWord arg3 )
1519{
1520 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1521 struct timespec *timeout); */
1522 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1523 if (arg3 != 0)
1524 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1525}
1526
1527/* ------ */
1528
1529static
1530UInt get_sem_count( Int semid )
1531{
sewardja8d8e232005-06-07 20:04:56 +00001532 struct vki_semid_ds buf;
1533 union vki_semun arg;
1534 SysRes res;
sewardjb369c5e2005-03-24 17:52:02 +00001535
sewardja8d8e232005-06-07 20:04:56 +00001536 arg.buf = &buf;
sewardjb369c5e2005-03-24 17:52:02 +00001537
sewardja8d8e232005-06-07 20:04:56 +00001538# ifdef __NR_semctl
1539 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
1540# else
1541 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
1542 VKI_IPC_STAT, (UWord)&arg);
1543# endif
1544 if (res.isError)
1545 return 0;
sewardjb369c5e2005-03-24 17:52:02 +00001546
sewardja8d8e232005-06-07 20:04:56 +00001547 return buf.sem_nsems;
sewardjb369c5e2005-03-24 17:52:02 +00001548}
1549
1550void
sewardj7eb7c582005-06-23 01:02:53 +00001551ML_(generic_PRE_sys_semctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001552 UWord arg0, UWord arg1,
1553 UWord arg2, UWord arg3 )
1554{
1555 /* int semctl(int semid, int semnum, int cmd, ...); */
1556 union vki_semun arg = *(union vki_semun *)&arg3;
1557 UInt nsems;
1558 switch (arg2 /* cmd */) {
1559 case VKI_IPC_INFO:
1560 case VKI_SEM_INFO:
1561 case VKI_IPC_INFO|VKI_IPC_64:
1562 case VKI_SEM_INFO|VKI_IPC_64:
1563 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
1564 (Addr)arg.buf, sizeof(struct vki_seminfo) );
1565 break;
1566 case VKI_IPC_STAT:
1567 case VKI_SEM_STAT:
1568 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1569 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1570 break;
1571 case VKI_IPC_STAT|VKI_IPC_64:
1572 case VKI_SEM_STAT|VKI_IPC_64:
1573 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
1574 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1575 break;
1576 case VKI_IPC_SET:
1577 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1578 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1579 break;
1580 case VKI_IPC_SET|VKI_IPC_64:
1581 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
1582 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1583 break;
1584 case VKI_GETALL:
1585 case VKI_GETALL|VKI_IPC_64:
1586 nsems = get_sem_count( arg0 );
1587 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
1588 (Addr)arg.array, sizeof(unsigned short) * nsems );
1589 break;
1590 case VKI_SETALL:
1591 case VKI_SETALL|VKI_IPC_64:
1592 nsems = get_sem_count( arg0 );
1593 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
1594 (Addr)arg.array, sizeof(unsigned short) * nsems );
1595 break;
1596 }
1597}
1598
1599void
sewardj7eb7c582005-06-23 01:02:53 +00001600ML_(generic_POST_sys_semctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001601 UWord res,
1602 UWord arg0, UWord arg1,
1603 UWord arg2, UWord arg3 )
1604{
1605 union vki_semun arg = *(union vki_semun *)&arg3;
1606 UInt nsems;
1607 switch (arg2 /* cmd */) {
1608 case VKI_IPC_INFO:
1609 case VKI_SEM_INFO:
1610 case VKI_IPC_INFO|VKI_IPC_64:
1611 case VKI_SEM_INFO|VKI_IPC_64:
1612 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
1613 break;
1614 case VKI_IPC_STAT:
1615 case VKI_SEM_STAT:
1616 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
1617 break;
1618 case VKI_IPC_STAT|VKI_IPC_64:
1619 case VKI_SEM_STAT|VKI_IPC_64:
1620 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
1621 break;
1622 case VKI_GETALL:
1623 case VKI_GETALL|VKI_IPC_64:
1624 nsems = get_sem_count( arg0 );
1625 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
1626 break;
1627 }
1628}
1629
1630/* ------ */
1631
sewardjb369c5e2005-03-24 17:52:02 +00001632/* ------ */
1633
1634static
1635UInt get_shm_size ( Int shmid )
1636{
sewardja8d8e232005-06-07 20:04:56 +00001637# ifdef __NR_shmctl
sewardjb369c5e2005-03-24 17:52:02 +00001638 struct vki_shmid64_ds buf;
sewardja8d8e232005-06-07 20:04:56 +00001639 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
1640# else
sewardjb369c5e2005-03-24 17:52:02 +00001641 struct vki_shmid_ds buf;
sewardja8d8e232005-06-07 20:04:56 +00001642 SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
sewardjb369c5e2005-03-24 17:52:02 +00001643 VKI_IPC_STAT, 0, (UWord)&buf);
sewardja8d8e232005-06-07 20:04:56 +00001644# endif
1645 if (__res.isError)
sewardjb369c5e2005-03-24 17:52:02 +00001646 return 0;
1647
1648 return buf.shm_segsz;
1649}
1650
1651UWord
sewardj7eb7c582005-06-23 01:02:53 +00001652ML_(generic_PRE_sys_shmat) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001653 UWord arg0, UWord arg1, UWord arg2 )
1654{
1655 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
sewardj45f4e7c2005-09-27 19:20:21 +00001656 UInt segmentSize = get_shm_size ( arg0 );
1657 UWord tmp;
1658 Bool ok;
1659 if (arg1 == 0) {
1660 tmp = VG_(am_get_advisory_client_simple)(0, segmentSize, &ok);
1661 if (ok)
1662 arg1 = tmp;
1663 }
sewardj7eb7c582005-06-23 01:02:53 +00001664 else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
sewardjb369c5e2005-03-24 17:52:02 +00001665 arg1 = 0;
1666 return arg1;
1667}
1668
1669void
sewardj7eb7c582005-06-23 01:02:53 +00001670ML_(generic_POST_sys_shmat) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001671 UWord res,
1672 UWord arg0, UWord arg1, UWord arg2 )
1673{
1674 UInt segmentSize = get_shm_size ( arg0 );
1675 if ( segmentSize > 0 ) {
1676 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
sewardj45f4e7c2005-09-27 19:20:21 +00001677 Bool d;
sewardjb369c5e2005-03-24 17:52:02 +00001678
tomf61fea02005-10-04 12:04:06 +00001679 if (arg2 & VKI_SHM_RDONLY)
sewardjb369c5e2005-03-24 17:52:02 +00001680 prot &= ~VKI_PROT_WRITE;
sewardj45f4e7c2005-09-27 19:20:21 +00001681 /* It isn't exactly correct to pass 0 for the fd and offset
1682 here. The kernel seems to think the corresponding section
1683 does have dev/ino numbers:
1684
1685 04e52000-04ec8000 rw-s 00000000 00:06 1966090 /SYSV00000000 (deleted)
1686
1687 However there is no obvious way to find them. In order to
1688 cope with the discrepancy, aspacem's sync checker omits the
1689 dev/ino correspondence check in cases where V does not know
1690 the dev/ino. */
tom1340c352005-10-04 15:59:54 +00001691 d = VG_(am_notify_client_shmat)( res, VG_PGROUNDUP(segmentSize), prot );
sewardj45f4e7c2005-09-27 19:20:21 +00001692
1693 /* we don't distinguish whether it's read-only or
1694 * read-write -- it doesn't matter really. */
1695 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
1696 if (d)
1697 VG_(discard_translations)( (Addr64)res,
1698 (ULong)VG_PGROUNDUP(segmentSize),
1699 "ML_(generic_POST_sys_shmat)" );
sewardjb369c5e2005-03-24 17:52:02 +00001700 }
1701}
1702
1703/* ------ */
1704
1705Bool
sewardj7eb7c582005-06-23 01:02:53 +00001706ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
sewardjb369c5e2005-03-24 17:52:02 +00001707{
1708 /* int shmdt(const void *shmaddr); */
sewardj7eb7c582005-06-23 01:02:53 +00001709 return ML_(valid_client_addr)(arg0, 1, tid, "shmdt");
sewardjb369c5e2005-03-24 17:52:02 +00001710}
1711
1712void
sewardj7eb7c582005-06-23 01:02:53 +00001713ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
sewardjb369c5e2005-03-24 17:52:02 +00001714{
sewardj45f4e7c2005-09-27 19:20:21 +00001715 NSegment* s = VG_(am_find_nsegment)(arg0);
sewardjb369c5e2005-03-24 17:52:02 +00001716
sewardj0e682c62005-09-28 20:05:31 +00001717 if (s != NULL) {
1718 Addr s_start = s->start;
1719 SizeT s_len = s->end+1 - s->start;
tom1340c352005-10-04 15:59:54 +00001720 Bool d;
1721
dirk7bc57fc2006-04-27 11:05:13 +00001722 vg_assert(s->kind == SkShmC);
1723 vg_assert(s->start == arg0);
tom1340c352005-10-04 15:59:54 +00001724
1725 d = VG_(am_notify_munmap)(s_start, s_len);
sewardj0e682c62005-09-28 20:05:31 +00001726 s = NULL; /* s is now invalid */
1727 VG_TRACK( die_mem_munmap, s_start, s_len );
sewardj45f4e7c2005-09-27 19:20:21 +00001728 if (d)
sewardj0e682c62005-09-28 20:05:31 +00001729 VG_(discard_translations)( (Addr64)s_start,
1730 (ULong)s_len,
sewardj45f4e7c2005-09-27 19:20:21 +00001731 "ML_(generic_POST_sys_shmdt)" );
sewardjb369c5e2005-03-24 17:52:02 +00001732 }
1733}
1734/* ------ */
1735
1736void
sewardj7eb7c582005-06-23 01:02:53 +00001737ML_(generic_PRE_sys_shmctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001738 UWord arg0, UWord arg1, UWord arg2 )
1739{
1740 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
1741 switch (arg1 /* cmd */) {
1742 case VKI_IPC_INFO:
1743 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1744 arg2, sizeof(struct vki_shminfo) );
1745 break;
1746 case VKI_IPC_INFO|VKI_IPC_64:
1747 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
1748 arg2, sizeof(struct vki_shminfo64) );
1749 break;
1750 case VKI_SHM_INFO:
1751 case VKI_SHM_INFO|VKI_IPC_64:
1752 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
1753 arg2, sizeof(struct vki_shm_info) );
1754 break;
1755 case VKI_IPC_STAT:
1756 case VKI_SHM_STAT:
1757 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
1758 arg2, sizeof(struct vki_shmid_ds) );
1759 break;
1760 case VKI_IPC_STAT|VKI_IPC_64:
1761 case VKI_SHM_STAT|VKI_IPC_64:
1762 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
1763 arg2, sizeof(struct vki_shmid64_ds) );
1764 break;
1765 case VKI_IPC_SET:
1766 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1767 arg2, sizeof(struct vki_shmid_ds) );
1768 break;
1769 case VKI_IPC_SET|VKI_IPC_64:
1770 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
1771 arg2, sizeof(struct vki_shmid64_ds) );
1772 break;
1773 }
1774}
1775
1776void
sewardj7eb7c582005-06-23 01:02:53 +00001777ML_(generic_POST_sys_shmctl) ( ThreadId tid,
sewardjb369c5e2005-03-24 17:52:02 +00001778 UWord res,
1779 UWord arg0, UWord arg1, UWord arg2 )
1780{
1781 switch (arg1 /* cmd */) {
1782 case VKI_IPC_INFO:
1783 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
1784 break;
1785 case VKI_IPC_INFO|VKI_IPC_64:
1786 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
1787 break;
1788 case VKI_SHM_INFO:
1789 case VKI_SHM_INFO|VKI_IPC_64:
1790 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
1791 break;
1792 case VKI_IPC_STAT:
1793 case VKI_SHM_STAT:
1794 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
1795 break;
1796 case VKI_IPC_STAT|VKI_IPC_64:
1797 case VKI_SHM_STAT|VKI_IPC_64:
1798 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
1799 break;
1800 }
1801}
1802
1803
1804/* ---------------------------------------------------------------------
tom9548a162005-09-30 08:07:53 +00001805 Generic handler for mmap
1806 ------------------------------------------------------------------ */
1807
tom6d85b042005-09-30 16:09:12 +00001808/*
1809 * Although mmap is specified by POSIX and the argument are generally
1810 * consistent across platforms the precise details of the low level
1811 * argument passing conventions differ. For example:
1812 *
1813 * - On x86-linux there is mmap (aka old_mmap) which takes the
1814 * arguments in a memory block and the offset in bytes; and
1815 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
1816 * way and the offset in pages.
1817 *
1818 * - On ppc32-linux there is mmap (aka sys_mmap) which takes the
1819 * arguments in the normal way and the offset in bytes; and
1820 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
1821 * way and the offset in pages.
1822 *
1823 * - On amd64-linux everything is simple and there is just the one
1824 * call, mmap (aka sys_mmap) which takes the arguments in the
1825 * normal way and the offset in bytes.
1826 *
1827 * To cope with all this we provide a generic handler function here
1828 * and then each platform implements one or more system call handlers
1829 * which call this generic routine after extracting and normalising
1830 * the arguments.
1831 */
1832
tom9548a162005-09-30 08:07:53 +00001833SysRes
1834ML_(generic_PRE_sys_mmap) ( ThreadId tid,
1835 UWord arg1, UWord arg2, UWord arg3,
sewardj274461d2005-10-02 17:01:41 +00001836 UWord arg4, UWord arg5, Off64T arg6 )
tom9548a162005-09-30 08:07:53 +00001837{
1838 Addr advised;
1839 SysRes sres;
1840 MapRequest mreq;
1841 Bool mreq_ok;
1842
1843 if (arg2 == 0) {
1844 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
1845 shall be established. */
1846 return VG_(mk_SysRes_Error)( VKI_EINVAL );
1847 }
1848
1849 if (!VG_IS_PAGE_ALIGNED(arg1)) {
1850 /* zap any misaligned addresses. */
1851 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
1852 to fail. Here, we catch them all. */
1853 return VG_(mk_SysRes_Error)( VKI_EINVAL );
1854 }
1855
sewardj7e21df82005-09-30 10:48:27 +00001856 if (!VG_IS_PAGE_ALIGNED(arg6)) {
1857 /* zap any misaligned offsets. */
1858 /* SuSV3 says: The off argument is constrained to be aligned and
1859 sized according to the value returned by sysconf() when
1860 passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
1861 return VG_(mk_SysRes_Error)( VKI_EINVAL );
1862 }
1863
tom9548a162005-09-30 08:07:53 +00001864 /* Figure out what kind of allocation constraints there are
1865 (fixed/hint/any), and ask aspacem what we should do. */
1866 mreq.start = arg1;
1867 mreq.len = arg2;
1868 if (arg4 & VKI_MAP_FIXED) {
1869 mreq.rkind = MFixed;
1870 } else
1871 if (arg1 != 0) {
1872 mreq.rkind = MHint;
1873 } else {
1874 mreq.rkind = MAny;
1875 }
1876
1877 /* Enquire ... */
1878 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
1879 if (!mreq_ok) {
1880 /* Our request was bounced, so we'd better fail. */
1881 return VG_(mk_SysRes_Error)( VKI_EINVAL );
1882 }
1883
1884 /* Otherwise we're OK (so far). Install aspacem's choice of
1885 address, and let the mmap go through. */
1886 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
1887 arg4 | VKI_MAP_FIXED,
1888 arg5, arg6);
1889
1890 if (!sres.isError) {
1891 /* Notify aspacem and the tool. */
1892 ML_(notify_aspacem_and_tool_of_mmap)(
1893 (Addr)sres.val, /* addr kernel actually assigned */
1894 arg2, arg3,
1895 arg4, /* the original flags value */
1896 arg5, arg6
1897 );
1898 /* Load symbols? */
sewardjf72cced2005-11-08 00:45:47 +00001899 VG_(di_notify_mmap)( (Addr)sres.val, False/*allow_SkFileV*/ );
tom9548a162005-09-30 08:07:53 +00001900 }
1901
1902 /* Stay sane */
1903 if (!sres.isError && (arg4 & VKI_MAP_FIXED))
1904 vg_assert(sres.val == arg1);
1905
1906 return sres;
1907}
1908
1909
1910/* ---------------------------------------------------------------------
nethercote4fa681f2004-11-08 17:51:39 +00001911 The Main Entertainment ... syscall wrappers
njn25e49d8e72002-09-23 09:36:25 +00001912 ------------------------------------------------------------------ */
sewardjde4a1d02002-03-22 01:27:54 +00001913
nethercote4fa681f2004-11-08 17:51:39 +00001914/* Note: the PRE() and POST() wrappers are for the actual functions
nethercote8ff888f2004-11-17 17:11:45 +00001915 implementing the system calls in the OS kernel. These mostly have
nethercote4fa681f2004-11-08 17:51:39 +00001916 names like sys_write(); a few have names like old_mmap(). See the
njnaf839f52005-06-23 03:27:57 +00001917 comment for ML_(syscall_table)[] for important info about the __NR_foo
nethercote8ff888f2004-11-17 17:11:45 +00001918 constants and their relationship to the sys_foo() functions.
nethercote4fa681f2004-11-08 17:51:39 +00001919
nethercote92b2fd52004-11-16 16:15:41 +00001920 Some notes about names used for syscalls and args:
1921 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
1922 ambiguity.
1923
1924 - For error messages, we generally use a somewhat generic name
1925 for the syscall (eg. "write" rather than "sys_write"). This should be
1926 good enough for the average user to understand what is happening,
1927 without confusing them with names like "sys_write".
1928
1929 - Also, for error messages the arg names are mostly taken from the man
1930 pages (even though many of those man pages are really for glibc
nethercote8ff888f2004-11-17 17:11:45 +00001931 functions of the same name), rather than from the OS kernel source,
nethercote92b2fd52004-11-16 16:15:41 +00001932 for the same reason -- a user presented with a "bogus foo(bar)" arg
1933 will most likely look at the "foo" man page to see which is the "bar"
1934 arg.
nethercote8b76fe52004-11-08 19:20:09 +00001935
nethercote9c311eb2004-11-12 18:20:12 +00001936 Note that we use our own vki_* types. The one exception is in
1937 PRE_REG_READn calls, where pointer types haven't been changed, because
1938 they don't need to be -- eg. for "foo*" to be used, the type foo need not
1939 be visible.
1940
nethercote4fa681f2004-11-08 17:51:39 +00001941 XXX: some of these are arch-specific, and should be factored out.
1942*/
1943
sewardja8d8e232005-06-07 20:04:56 +00001944#define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
1945#define POST(name) DEFN_POST_TEMPLATE(generic, name)
jsgf855d93d2003-10-13 22:26:55 +00001946
sewardje7aa4ae2005-06-09 12:43:42 +00001947// Combine two 32-bit values into a 64-bit value
1948#define LOHI64(lo,hi) ( (lo) | ((ULong)(hi) << 32) )
1949
sewardja8d8e232005-06-07 20:04:56 +00001950//zz //PRE(sys_exit_group, Special)
1951//zz //{
1952//zz // VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
1953//zz //}
nethercoteef0c7662004-11-06 15:38:43 +00001954
sewardja8d8e232005-06-07 20:04:56 +00001955PRE(sys_exit)
jsgf855d93d2003-10-13 22:26:55 +00001956{
sewardja8d8e232005-06-07 20:04:56 +00001957 ThreadState* tst;
sewardja922b612005-03-11 02:47:32 +00001958 /* simple; just make this thread exit */
1959 PRINT("exit( %d )", ARG1);
1960 PRE_REG_READ1(void, "exit", int, exitcode);
sewardja8d8e232005-06-07 20:04:56 +00001961 tst = VG_(get_ThreadState)(tid);
1962 /* Set the thread's status to be exiting, then claim that the
1963 syscall succeeded. */
sewardja922b612005-03-11 02:47:32 +00001964 tst->exitreason = VgSrc_ExitSyscall;
1965 tst->os_state.exitcode = ARG1;
sewardja8d8e232005-06-07 20:04:56 +00001966 SET_STATUS_Success(0);
jsgf855d93d2003-10-13 22:26:55 +00001967}
1968
sewardja8d8e232005-06-07 20:04:56 +00001969PRE(sys_ni_syscall)
nethercoteeb1c7b72004-11-11 19:43:50 +00001970{
1971 PRINT("non-existent syscall! (ni_syscall)");
1972 PRE_REG_READ0(long, "ni_syscall");
sewardja8d8e232005-06-07 20:04:56 +00001973 SET_STATUS_Failure( VKI_ENOSYS );
nethercoteeb1c7b72004-11-11 19:43:50 +00001974}
1975
sewardj696c5512005-06-08 23:38:32 +00001976PRE(sys_iopl)
1977{
1978 PRINT("sys_iopl ( %d )", ARG1);
1979 PRE_REG_READ1(long, "iopl", unsigned long, level);
1980}
1981
sewardje6d5e722005-06-10 10:27:55 +00001982// XXX: this wrapper is only suitable for 32-bit platforms
1983#if defined(VGP_x86_linux)
1984PRE(sys_lookup_dcookie)
1985{
1986 PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
1987 PRE_REG_READ4(long, "lookup_dcookie",
1988 vki_u32, cookie_low32, vki_u32, cookie_high32,
1989 char *, buf, vki_size_t, len);
1990 PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
1991}
1992POST(sys_lookup_dcookie)
1993{
1994 vg_assert(SUCCESS);
1995 if (ARG3 != (Addr)NULL)
1996 POST_MEM_WRITE( ARG3, RES);
1997}
1998#endif
sewardj78b50e42005-06-08 01:47:28 +00001999
2000PRE(sys_fsync)
2001{
2002 *flags |= SfMayBlock;
2003 PRINT("sys_fsync ( %d )", ARG1);
2004 PRE_REG_READ1(long, "fsync", unsigned int, fd);
2005}
2006
sewardj696c5512005-06-08 23:38:32 +00002007PRE(sys_fdatasync)
2008{
2009 *flags |= SfMayBlock;
2010 PRINT("sys_fdatasync ( %d )", ARG1);
2011 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
2012}
2013
2014PRE(sys_msync)
2015{
2016 *flags |= SfMayBlock;
2017 PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
2018 PRE_REG_READ3(long, "msync",
2019 unsigned long, start, vki_size_t, length, int, flags);
2020 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
2021}
2022
sewardje6d5e722005-06-10 10:27:55 +00002023// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
2024// versions of LiS (Linux Streams). They are not part of the kernel.
2025// Therefore, we have to provide this type ourself, rather than getting it
2026// from the kernel sources.
2027struct vki_pmsg_strbuf {
2028 int maxlen; /* no. of bytes in buffer */
2029 int len; /* no. of bytes returned */
2030 vki_caddr_t buf; /* pointer to data */
2031};
2032PRE(sys_getpmsg)
2033{
2034 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
2035 struct vki_pmsg_strbuf *ctrl;
2036 struct vki_pmsg_strbuf *data;
2037 *flags |= SfMayBlock;
2038 PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
2039 PRE_REG_READ5(int, "getpmsg",
2040 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2041 int *, bandp, int *, flagsp);
2042 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2043 data = (struct vki_pmsg_strbuf *)ARG3;
2044 if (ctrl && ctrl->maxlen > 0)
2045 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
2046 if (data && data->maxlen > 0)
2047 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
2048 if (ARG4)
2049 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
2050 if (ARG5)
2051 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
2052}
2053POST(sys_getpmsg)
2054{
2055 struct vki_pmsg_strbuf *ctrl;
2056 struct vki_pmsg_strbuf *data;
2057 vg_assert(SUCCESS);
2058 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2059 data = (struct vki_pmsg_strbuf *)ARG3;
2060 if (RES == 0 && ctrl && ctrl->len > 0) {
2061 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
2062 }
2063 if (RES == 0 && data && data->len > 0) {
2064 POST_MEM_WRITE( (Addr)data->buf, data->len);
2065 }
2066}
2067
2068PRE(sys_putpmsg)
2069{
2070 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
2071 struct vki_pmsg_strbuf *ctrl;
2072 struct vki_pmsg_strbuf *data;
2073 *flags |= SfMayBlock;
2074 PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
2075 PRE_REG_READ5(int, "putpmsg",
2076 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2077 int, band, int, flags);
2078 ctrl = (struct vki_pmsg_strbuf *)ARG2;
2079 data = (struct vki_pmsg_strbuf *)ARG3;
2080 if (ctrl && ctrl->len > 0)
2081 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
2082 if (data && data->len > 0)
2083 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
2084}
sewardj696c5512005-06-08 23:38:32 +00002085
2086PRE(sys_getitimer)
2087{
2088 PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
2089 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
2090 PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
2091}
sewardj696c5512005-06-08 23:38:32 +00002092POST(sys_getitimer)
2093{
2094 if (ARG2 != (Addr)NULL) {
2095 POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
2096 }
2097}
2098
2099PRE(sys_setitimer)
2100{
2101 PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
2102 PRE_REG_READ3(long, "setitimer",
2103 int, which,
2104 struct itimerval *, value, struct itimerval *, ovalue);
2105 if (ARG2 != (Addr)NULL)
2106 PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
2107 if (ARG3 != (Addr)NULL)
2108 PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
2109}
2110
2111POST(sys_setitimer)
2112{
2113 if (ARG3 != (Addr)NULL) {
2114 POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
2115 }
2116}
2117
2118PRE(sys_chroot)
2119{
2120 PRINT("sys_chroot ( %p )", ARG1);
2121 PRE_REG_READ1(long, "chroot", const char *, path);
2122 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
2123}
sewardja8d8e232005-06-07 20:04:56 +00002124
2125PRE(sys_madvise)
jsgf855d93d2003-10-13 22:26:55 +00002126{
sewardja8d8e232005-06-07 20:04:56 +00002127 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00002128 PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercoteac866b92004-11-15 20:23:15 +00002129 PRE_REG_READ3(long, "madvise",
2130 unsigned long, start, vki_size_t, length, int, advice);
jsgf855d93d2003-10-13 22:26:55 +00002131}
2132
sewardja8d8e232005-06-07 20:04:56 +00002133PRE(sys_mremap)
jsgf855d93d2003-10-13 22:26:55 +00002134{
nethercote27ea8bc2004-07-10 17:21:14 +00002135 // Nb: this is different to the glibc version described in the man pages,
2136 // which lacks the fifth 'new_address' argument.
tomc00fcc72006-05-08 11:58:06 +00002137 if (ARG4 & VKI_MREMAP_FIXED) {
2138 PRINT("sys_mremap ( %p, %llu, %d, 0x%x, %p )",
2139 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5);
2140 PRE_REG_READ5(unsigned long, "mremap",
2141 unsigned long, old_addr, unsigned long, old_size,
2142 unsigned long, new_size, unsigned long, flags,
2143 unsigned long, new_addr);
2144 } else {
2145 PRINT("sys_mremap ( %p, %llu, %d, 0x%x )",
2146 ARG1, (ULong)ARG2, ARG3, ARG4);
2147 PRE_REG_READ4(unsigned long, "mremap",
2148 unsigned long, old_addr, unsigned long, old_size,
2149 unsigned long, new_size, unsigned long, flags);
2150 }
sewardja8d8e232005-06-07 20:04:56 +00002151 SET_STATUS_from_SysRes(
sewardj45f4e7c2005-09-27 19:20:21 +00002152 do_mremap((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
sewardja8d8e232005-06-07 20:04:56 +00002153 );
jsgf855d93d2003-10-13 22:26:55 +00002154}
2155
sewardj8c9ea4e2005-06-08 10:46:56 +00002156PRE(sys_nice)
2157{
2158 PRINT("sys_nice ( %d )", ARG1);
2159 PRE_REG_READ1(long, "nice", int, inc);
2160}
sewardj78b50e42005-06-08 01:47:28 +00002161
sewardj696c5512005-06-08 23:38:32 +00002162PRE(sys_mlock)
2163{
2164 *flags |= SfMayBlock;
2165 PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
2166 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
2167}
2168
2169PRE(sys_munlock)
2170{
2171 *flags |= SfMayBlock;
2172 PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
2173 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
2174}
2175
2176PRE(sys_mlockall)
2177{
2178 *flags |= SfMayBlock;
2179 PRINT("sys_mlockall ( %x )", ARG1);
2180 PRE_REG_READ1(long, "mlockall", int, flags);
2181}
2182
sewardj696c5512005-06-08 23:38:32 +00002183PRE(sys_setpriority)
2184{
2185 PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
2186 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
2187}
2188
2189PRE(sys_getpriority)
2190{
2191 PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
2192 PRE_REG_READ2(long, "getpriority", int, which, int, who);
2193}
2194
tom4f08a652005-07-05 23:25:17 +00002195// The actual kernel definition of this routine takes a
2196// single 64 bit offset argument. This version is for 32 bit
2197// platforms only and treats the offset as two values - the
2198// kernel relies on stack based argument passing conventions
2199// to merge the two together.
sewardje6d5e722005-06-10 10:27:55 +00002200PRE(sys_pwrite64)
2201{
2202 *flags |= SfMayBlock;
2203 PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
2204 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
2205 PRE_REG_READ5(ssize_t, "pwrite64",
2206 unsigned int, fd, const char *, buf, vki_size_t, count,
2207 vki_u32, offset_low32, vki_u32, offset_high32);
2208 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
2209}
sewardj8c9ea4e2005-06-08 10:46:56 +00002210
2211PRE(sys_sync)
2212{
2213 *flags |= SfMayBlock;
2214 PRINT("sys_sync ( )");
2215 PRE_REG_READ0(long, "sync");
2216}
2217
sewardj696c5512005-06-08 23:38:32 +00002218PRE(sys_fstatfs)
2219{
2220 PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
2221 PRE_REG_READ2(long, "fstatfs",
2222 unsigned int, fd, struct statfs *, buf);
2223 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
2224}
2225
2226POST(sys_fstatfs)
2227{
2228 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
2229}
2230
sewardje6d5e722005-06-10 10:27:55 +00002231PRE(sys_fstatfs64)
2232{
2233 PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
2234 PRE_REG_READ3(long, "fstatfs64",
2235 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
2236 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
2237}
2238POST(sys_fstatfs64)
2239{
2240 POST_MEM_WRITE( ARG3, ARG2 );
2241}
sewardj696c5512005-06-08 23:38:32 +00002242
2243PRE(sys_getsid)
2244{
2245 PRINT("sys_getsid ( %d )", ARG1);
2246 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
2247}
2248
tom4f08a652005-07-05 23:25:17 +00002249// The actual kernel definition of this routine takes a
2250// single 64 bit offset argument. This version is for 32 bit
2251// platforms only and treats the offset as two values - the
2252// kernel relies on stack based argument passing conventions
2253// to merge the two together.
sewardje7aa4ae2005-06-09 12:43:42 +00002254PRE(sys_pread64)
2255{
2256 *flags |= SfMayBlock;
2257 PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
2258 ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
2259 PRE_REG_READ5(ssize_t, "pread64",
2260 unsigned int, fd, char *, buf, vki_size_t, count,
2261 vki_u32, offset_low32, vki_u32, offset_high32);
2262 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
2263}
2264POST(sys_pread64)
2265{
2266 vg_assert(SUCCESS);
2267 if (RES > 0) {
2268 POST_MEM_WRITE( ARG2, RES );
2269 }
2270}
jsgf855d93d2003-10-13 22:26:55 +00002271
sewardja8d8e232005-06-07 20:04:56 +00002272PRE(sys_mknod)
jsgf855d93d2003-10-13 22:26:55 +00002273{
tom363ec762006-03-21 10:58:35 +00002274 PRINT("sys_mknod ( %p(%s), 0x%x, 0x%x )", ARG1, ARG1, ARG2, ARG3 );
nethercotec6851dd2004-11-11 18:00:47 +00002275 PRE_REG_READ3(long, "mknod",
2276 const char *, pathname, int, mode, unsigned, dev);
njn22cfccb2004-11-27 16:10:23 +00002277 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002278}
2279
sewardj696c5512005-06-08 23:38:32 +00002280PRE(sys_flock)
2281{
2282 *flags |= SfMayBlock;
2283 PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
2284 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
2285}
2286
2287/* This surely isn't remotely generic -- move to linux-specifics? */
2288PRE(sys_init_module)
2289{
2290 *flags |= SfMayBlock;
2291 PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
2292 PRE_REG_READ3(long, "init_module",
2293 void *, umod, unsigned long, len, const char *, uargs);
2294 PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
2295 PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
2296}
2297
nethercotea81e9162004-02-12 14:34:14 +00002298// Pre_read a char** argument.
sewardjb5f6f512005-03-10 23:59:00 +00002299static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
nethercotea81e9162004-02-12 14:34:14 +00002300{
2301 while (True) {
njnb249fd72004-11-29 14:24:57 +00002302 Addr a_deref;
2303 Addr* a_p = (Addr*)a;
2304 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
2305 a_deref = *a_p;
nethercotea81e9162004-02-12 14:34:14 +00002306 if (0 == a_deref)
2307 break;
nethercoteef0c7662004-11-06 15:38:43 +00002308 PRE_MEM_RASCIIZ( s2, a_deref );
nethercotea81e9162004-02-12 14:34:14 +00002309 a += sizeof(char*);
2310 }
2311}
2312
njn7b85dd52005-06-12 17:26:29 +00002313static Bool i_am_the_only_thread ( void )
2314{
2315 Int c = VG_(count_living_threads)();
2316 vg_assert(c >= 1); /* stay sane */
2317 return c == 1;
2318}
2319
2320/* Wait until all other threads disappear. */
2321void VG_(reap_threads)(ThreadId self)
2322{
2323 while (!i_am_the_only_thread()) {
2324 /* Let other thread(s) run */
2325 VG_(vg_yield)();
2326 VG_(poll_signals)(self);
2327 }
2328 vg_assert(i_am_the_only_thread());
2329}
2330
nethercote7310afb2004-11-12 15:41:06 +00002331// XXX: prototype here seemingly doesn't match the prototype for i386-linux,
2332// but it seems to work nonetheless...
sewardja8d8e232005-06-07 20:04:56 +00002333PRE(sys_execve)
jsgf855d93d2003-10-13 22:26:55 +00002334{
sewardj45f4e7c2005-09-27 19:20:21 +00002335 Char* path = NULL; /* path to executable */
tom13696cc2005-07-18 23:23:03 +00002336 Char** envp = NULL;
sewardj45f4e7c2005-09-27 19:20:21 +00002337 Char** argv = NULL;
2338 Char** arg2copy;
2339 Char* launcher_basename = NULL;
sewardja8d8e232005-06-07 20:04:56 +00002340 ThreadState* tst;
sewardj45f4e7c2005-09-27 19:20:21 +00002341 Int i, j, tot_args;
njn73750612005-10-14 03:11:30 +00002342 SysRes res;
sewardjb5f6f512005-03-10 23:59:00 +00002343
njn22cfccb2004-11-27 16:10:23 +00002344 PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
nethercote7310afb2004-11-12 15:41:06 +00002345 PRE_REG_READ3(vki_off_t, "execve",
2346 char *, filename, char **, argv, char **, envp);
njn22cfccb2004-11-27 16:10:23 +00002347 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
2348 if (ARG2 != 0)
2349 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
2350 if (ARG3 != 0)
2351 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
fitzhardingee1c06d82003-10-30 07:21:44 +00002352
sewardja8d8e232005-06-07 20:04:56 +00002353 vg_assert(VG_(is_valid_tid)(tid));
2354 tst = VG_(get_ThreadState)(tid);
2355
fitzhardingee1c06d82003-10-30 07:21:44 +00002356 /* Erk. If the exec fails, then the following will have made a
2357 mess of things which makes it hard for us to continue. The
2358 right thing to do is piece everything together again in
sewardj45f4e7c2005-09-27 19:20:21 +00002359 POST(execve), but that's close to impossible. Instead, we make
2360 an effort to check that the execve will work before actually
2361 doing it. */
fitzhardingee1c06d82003-10-30 07:21:44 +00002362
njn73750612005-10-14 03:11:30 +00002363 /* Check that the name at least begins in client-accessible storage. */
sewardj45f4e7c2005-09-27 19:20:21 +00002364 if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
2365 SET_STATUS_Failure( VKI_EFAULT );
2366 return;
2367 }
2368
njn73750612005-10-14 03:11:30 +00002369 // Do the important checks: it is a file, is executable, permissions are
2370 // ok, etc.
2371 res = VG_(pre_exec_check)((const Char*)ARG1, NULL);
2372 if (res.isError) {
2373 SET_STATUS_Failure( res.val );
2374 return;
2375 }
2376
sewardj98e68a42005-10-04 23:07:33 +00002377 /* If we're tracing the child, and the launcher name looks bogus
2378 (possibly because launcher.c couldn't figure it out, see
2379 comments therein) then we have no option but to fail. */
2380 if (VG_(clo_trace_children)
2381 && (VG_(name_of_launcher) == NULL
2382 || VG_(name_of_launcher)[0] != '/')) {
2383 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
2384 return;
2385 }
2386
sewardj45f4e7c2005-09-27 19:20:21 +00002387 /* After this point, we can't recover if the execve fails. */
2388 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (Char*)ARG1);
2389
fitzhardingee1c06d82003-10-30 07:21:44 +00002390 /* Resistance is futile. Nuke all other threads. POSIX mandates
2391 this. (Really, nuke them all, since the new process will make
2392 its own new thread.) */
sewardjb5f6f512005-03-10 23:59:00 +00002393 VG_(nuke_all_threads_except)( tid, VgSrc_ExitSyscall );
njn7b85dd52005-06-12 17:26:29 +00002394 VG_(reap_threads)(tid);
sewardjb5f6f512005-03-10 23:59:00 +00002395
sewardj45f4e7c2005-09-27 19:20:21 +00002396 // Set up the child's exe path.
2397 //
2398 if (VG_(clo_trace_children)) {
2399
2400 // We want to exec the launcher. Get its pre-remembered path.
2401 path = VG_(name_of_launcher);
2402 // VG_(name_of_launcher) should have been acquired by m_main at
2403 // startup.
2404 vg_assert(path);
2405
2406 launcher_basename = VG_(strrchr)(path, '/');
2407 if (launcher_basename == NULL || launcher_basename[1] == 0) {
2408 launcher_basename = path; // hmm, tres dubious
2409 } else {
2410 launcher_basename++;
2411 }
2412
2413 } else {
2414 path = (Char*)ARG1;
2415 }
2416
2417 // Set up the child's environment.
2418 //
tom4e136952005-07-18 14:02:11 +00002419 // Remove the valgrind-specific stuff from the environment so the
njn7b4e5ba2005-08-25 22:53:57 +00002420 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
tom4e136952005-07-18 14:02:11 +00002421 // This is done unconditionally, since if we are tracing the child,
sewardj45f4e7c2005-09-27 19:20:21 +00002422 // the child valgrind will set up the appropriate client environment.
njn11106992005-07-18 14:10:12 +00002423 // Nb: we make a copy of the environment before trying to mangle it
2424 // as it might be in read-only memory (this was bug #101881).
sewardj45f4e7c2005-09-27 19:20:21 +00002425 //
2426 // Then, if tracing the child, set VALGRIND_LIB for it.
2427 //
2428 if (ARG3 == 0) {
2429 envp = NULL;
2430 } else {
tom13696cc2005-07-18 23:23:03 +00002431 envp = VG_(env_clone)( (Char**)ARG3 );
sewardj45f4e7c2005-09-27 19:20:21 +00002432 if (envp == NULL) goto hosed;
tom4e136952005-07-18 14:02:11 +00002433 VG_(env_remove_valgrind_env_stuff)( envp );
fitzhardinge5408c062004-01-04 23:52:59 +00002434 }
2435
2436 if (VG_(clo_trace_children)) {
sewardj45f4e7c2005-09-27 19:20:21 +00002437 // Set VALGRIND_LIB in ARG3 (the environment)
2438 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
fitzhardinge98abfc72003-12-16 02:05:15 +00002439 }
2440
sewardj45f4e7c2005-09-27 19:20:21 +00002441 // Set up the child's args. If not tracing it, they are
2442 // simply ARG2. Otherwise, they are
2443 //
2444 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG2[1..]
2445 //
2446 // except that the first VG_(args_for_valgrind_noexecpass) args
2447 // are omitted.
2448 //
2449 if (!VG_(clo_trace_children)) {
2450 argv = (Char**)ARG2;
2451 } else {
2452 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
2453 vg_assert( VG_(args_for_valgrind_noexecpass)
2454 <= VG_(args_for_valgrind).used );
2455 /* how many args in total will there be? */
2456 // launcher basename
2457 tot_args = 1;
2458 // V's args
2459 tot_args += VG_(args_for_valgrind).used;
2460 tot_args -= VG_(args_for_valgrind_noexecpass);
2461 // name of client exe
2462 tot_args++;
2463 // args for client exe, skipping [0]
2464 arg2copy = (Char**)ARG2;
2465 if (arg2copy && arg2copy[0]) {
2466 for (i = 1; arg2copy[i]; i++)
2467 tot_args++;
2468 }
2469 // allocate
2470 argv = VG_(malloc)( (tot_args+1) * sizeof(HChar*) );
2471 if (argv == 0) goto hosed;
2472 // copy
2473 j = 0;
2474 argv[j++] = launcher_basename;
2475 for (i = 0; i < VG_(args_for_valgrind).used; i++) {
2476 if (i < VG_(args_for_valgrind_noexecpass))
2477 continue;
2478 argv[j++] = VG_(args_for_valgrind).strs[i];
2479 }
2480 argv[j++] = (Char*)ARG1;
2481 if (arg2copy && arg2copy[0])
2482 for (i = 1; arg2copy[i]; i++)
2483 argv[j++] = arg2copy[i];
2484 argv[j++] = NULL;
2485 // check
2486 vg_assert(j == tot_args+1);
jsgf855d93d2003-10-13 22:26:55 +00002487 }
jsgf855d93d2003-10-13 22:26:55 +00002488
sewardjb5f6f512005-03-10 23:59:00 +00002489 /* restore the DATA rlimit for the child */
2490 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
2491
2492 /*
2493 Set the signal state up for exec.
2494
2495 We need to set the real signal state to make sure the exec'd
2496 process gets SIG_IGN properly.
2497
2498 Also set our real sigmask to match the client's sigmask so that
2499 the exec'd child will get the right mask. First we need to
2500 clear out any pending signals so they they don't get delivered,
2501 which would confuse things.
fitzhardingef0dd7e12004-01-16 02:17:30 +00002502
2503 XXX This is a bug - the signals should remain pending, and be
2504 delivered to the new process after exec. There's also a
2505 race-condition, since if someone delivers us a signal between
2506 the sigprocmask and the execve, we'll still get the signal. Oh
2507 well.
2508 */
2509 {
nethercote73b526f2004-10-31 18:48:21 +00002510 vki_sigset_t allsigs;
2511 vki_siginfo_t info;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002512 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00002513
sewardj45f4e7c2005-09-27 19:20:21 +00002514 for (i = 1; i < VG_(max_signal); i++) {
sewardjb5f6f512005-03-10 23:59:00 +00002515 struct vki_sigaction sa;
2516 VG_(do_sys_sigaction)(i, NULL, &sa);
2517 if (sa.ksa_handler == VKI_SIG_IGN)
2518 VG_(sigaction)(i, &sa, NULL);
2519 else {
2520 sa.ksa_handler = VKI_SIG_DFL;
2521 VG_(sigaction)(i, &sa, NULL);
2522 }
2523 }
2524
nethercote73b526f2004-10-31 18:48:21 +00002525 VG_(sigfillset)(&allsigs);
2526 while(VG_(sigtimedwait)(&allsigs, &info, &zero) > 0)
sewardjb5f6f512005-03-10 23:59:00 +00002527 ;
fitzhardingef0dd7e12004-01-16 02:17:30 +00002528
nethercote73b526f2004-10-31 18:48:21 +00002529 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
fitzhardingef0dd7e12004-01-16 02:17:30 +00002530 }
2531
sewardj45f4e7c2005-09-27 19:20:21 +00002532 if (0) {
2533 Char **cpp;
2534 VG_(printf)("exec: %s\n", path);
2535 for (cpp = argv; cpp && *cpp; cpp++)
2536 VG_(printf)("argv: %s\n", *cpp);
2537 if (0)
2538 for (cpp = envp; cpp && *cpp; cpp++)
2539 VG_(printf)("env: %s\n", *cpp);
2540 }
2541
sewardja8d8e232005-06-07 20:04:56 +00002542 SET_STATUS_from_SysRes(
sewardj45f4e7c2005-09-27 19:20:21 +00002543 VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp)
sewardja8d8e232005-06-07 20:04:56 +00002544 );
fitzhardingeb50068f2004-02-24 23:42:55 +00002545
sewardj45f4e7c2005-09-27 19:20:21 +00002546 /* If we got here, then the execve failed. We've already made way
2547 too much of a mess to continue, so we have to abort. */
2548 hosed:
tomdc294c32005-08-16 10:19:58 +00002549 vg_assert(FAILURE);
nethercotee70bd7d2004-08-18 14:37:17 +00002550 VG_(message)(Vg_UserMsg, "execve(%p(%s), %p, %p) failed, errno %d",
tomdc294c32005-08-16 10:19:58 +00002551 ARG1, ARG1, ARG2, ARG3, RES_unchecked);
sewardjb5f6f512005-03-10 23:59:00 +00002552 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
2553 "execve() failing, so I'm dying.");
sewardja8d8e232005-06-07 20:04:56 +00002554 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
sewardjb5f6f512005-03-10 23:59:00 +00002555 "or work out how to recover.");
2556 VG_(exit)(101);
jsgf855d93d2003-10-13 22:26:55 +00002557}
2558
sewardja8d8e232005-06-07 20:04:56 +00002559PRE(sys_access)
jsgf855d93d2003-10-13 22:26:55 +00002560{
njn22cfccb2004-11-27 16:10:23 +00002561 PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00002562 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00002563 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002564}
2565
sewardja8d8e232005-06-07 20:04:56 +00002566PRE(sys_alarm)
jsgf855d93d2003-10-13 22:26:55 +00002567{
njn22cfccb2004-11-27 16:10:23 +00002568 PRINT("sys_alarm ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002569 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
jsgf855d93d2003-10-13 22:26:55 +00002570}
2571
sewardja8d8e232005-06-07 20:04:56 +00002572PRE(sys_brk)
jsgf855d93d2003-10-13 22:26:55 +00002573{
fitzhardinge98abfc72003-12-16 02:05:15 +00002574 Addr brk_limit = VG_(brk_limit);
sewardja8d8e232005-06-07 20:04:56 +00002575 Addr brk_new;
fitzhardinge98abfc72003-12-16 02:05:15 +00002576
jsgf855d93d2003-10-13 22:26:55 +00002577 /* libc says: int brk(void *end_data_segment);
2578 kernel says: void* brk(void* end_data_segment); (more or less)
2579
2580 libc returns 0 on success, and -1 (and sets errno) on failure.
2581 Nb: if you ask to shrink the dataseg end below what it
2582 currently is, that always succeeds, even if the dataseg end
2583 doesn't actually change (eg. brk(0)). Unless it seg faults.
2584
2585 Kernel returns the new dataseg end. If the brk() failed, this
2586 will be unchanged from the old one. That's why calling (kernel)
2587 brk(0) gives the current dataseg end (libc brk() just returns
2588 zero in that case).
2589
2590 Both will seg fault if you shrink it back into a text segment.
2591 */
njn22cfccb2004-11-27 16:10:23 +00002592 PRINT("sys_brk ( %p )", ARG1);
nethercote9c311eb2004-11-12 18:20:12 +00002593 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
jsgf855d93d2003-10-13 22:26:55 +00002594
sewardja8d8e232005-06-07 20:04:56 +00002595 brk_new = do_brk(ARG1);
2596 SET_STATUS_Success( brk_new );
fitzhardinge98abfc72003-12-16 02:05:15 +00002597
sewardja8d8e232005-06-07 20:04:56 +00002598 if (brk_new == ARG1) {
jsgf855d93d2003-10-13 22:26:55 +00002599 /* brk() succeeded */
sewardja8d8e232005-06-07 20:04:56 +00002600 if (brk_new < brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002601 /* successfully shrunk the data segment. */
njn22cfccb2004-11-27 16:10:23 +00002602 VG_TRACK( die_mem_brk, (Addr)ARG1,
2603 brk_limit-ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002604 } else
sewardja8d8e232005-06-07 20:04:56 +00002605 if (brk_new > brk_limit) {
jsgf855d93d2003-10-13 22:26:55 +00002606 /* successfully grew the data segment */
fitzhardinge98abfc72003-12-16 02:05:15 +00002607 VG_TRACK( new_mem_brk, brk_limit,
njn22cfccb2004-11-27 16:10:23 +00002608 ARG1-brk_limit );
jsgf855d93d2003-10-13 22:26:55 +00002609 }
jsgf855d93d2003-10-13 22:26:55 +00002610 } else {
2611 /* brk() failed */
sewardja8d8e232005-06-07 20:04:56 +00002612 vg_assert(brk_limit == brk_new);
jsgf855d93d2003-10-13 22:26:55 +00002613 }
2614}
2615
sewardja8d8e232005-06-07 20:04:56 +00002616PRE(sys_chdir)
jsgf855d93d2003-10-13 22:26:55 +00002617{
tom363ec762006-03-21 10:58:35 +00002618 PRINT("sys_chdir ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002619 PRE_REG_READ1(long, "chdir", const char *, path);
njn22cfccb2004-11-27 16:10:23 +00002620 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002621}
2622
sewardja8d8e232005-06-07 20:04:56 +00002623PRE(sys_chmod)
jsgf855d93d2003-10-13 22:26:55 +00002624{
tom363ec762006-03-21 10:58:35 +00002625 PRINT("sys_chmod ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00002626 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
njn22cfccb2004-11-27 16:10:23 +00002627 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00002628}
2629
sewardje6d5e722005-06-10 10:27:55 +00002630PRE(sys_chown)
2631{
tom363ec762006-03-21 10:58:35 +00002632 PRINT("sys_chown ( %p(%s), 0x%x, 0x%x )", ARG1,ARG1,ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +00002633 PRE_REG_READ3(long, "chown",
2634 const char *, path, vki_uid_t, owner, vki_gid_t, group);
2635 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
2636}
2637
2638PRE(sys_lchown)
2639{
tom363ec762006-03-21 10:58:35 +00002640 PRINT("sys_lchown ( %p(%s), 0x%x, 0x%x )", ARG1,ARG1,ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +00002641 PRE_REG_READ3(long, "lchown",
2642 const char *, path, vki_uid_t, owner, vki_gid_t, group);
2643 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
2644}
nethercote2e1c37d2004-11-13 13:57:12 +00002645
sewardja8d8e232005-06-07 20:04:56 +00002646PRE(sys_close)
jsgf855d93d2003-10-13 22:26:55 +00002647{
njn22cfccb2004-11-27 16:10:23 +00002648 PRINT("sys_close ( %d )", ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00002649 PRE_REG_READ1(long, "close", unsigned int, fd);
2650
nethercotef8548672004-06-21 12:42:35 +00002651 /* Detect and negate attempts by the client to close Valgrind's log fd */
sewardj7eb7c582005-06-23 01:02:53 +00002652 if (!ML_(fd_allowed)(ARG1, "close", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00002653 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002654}
2655
nethercote85a456f2004-11-16 17:31:56 +00002656POST(sys_close)
rjwalshf5f536f2003-11-17 17:45:00 +00002657{
njn22cfccb2004-11-27 16:10:23 +00002658 if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
rjwalshf5f536f2003-11-17 17:45:00 +00002659}
jsgf855d93d2003-10-13 22:26:55 +00002660
sewardja8d8e232005-06-07 20:04:56 +00002661PRE(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002662{
njn22cfccb2004-11-27 16:10:23 +00002663 PRINT("sys_dup ( %d )", ARG1);
nethercote9a3beb92004-11-12 17:07:26 +00002664 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
jsgf855d93d2003-10-13 22:26:55 +00002665}
2666
nethercote85a456f2004-11-16 17:31:56 +00002667POST(sys_dup)
jsgf855d93d2003-10-13 22:26:55 +00002668{
sewardja8d8e232005-06-07 20:04:56 +00002669 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00002670 if (!ML_(fd_allowed)(RES, "dup", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00002671 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00002672 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00002673 } else {
nethercote9a3beb92004-11-12 17:07:26 +00002674 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002675 record_fd_open_named(tid, RES);
jsgf855d93d2003-10-13 22:26:55 +00002676 }
2677}
2678
sewardja8d8e232005-06-07 20:04:56 +00002679PRE(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002680{
njn22cfccb2004-11-27 16:10:23 +00002681 PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
nethercote71f05f32004-11-12 18:49:27 +00002682 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
sewardj7eb7c582005-06-23 01:02:53 +00002683 if (!ML_(fd_allowed)(ARG2, "dup2", tid, True))
sewardja8d8e232005-06-07 20:04:56 +00002684 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00002685}
2686
nethercote85a456f2004-11-16 17:31:56 +00002687POST(sys_dup2)
jsgf855d93d2003-10-13 22:26:55 +00002688{
sewardja8d8e232005-06-07 20:04:56 +00002689 vg_assert(SUCCESS);
nethercote71f05f32004-11-12 18:49:27 +00002690 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002691 record_fd_open_named(tid, RES);
jsgf855d93d2003-10-13 22:26:55 +00002692}
2693
sewardj696c5512005-06-08 23:38:32 +00002694PRE(sys_fchdir)
2695{
2696 PRINT("sys_fchdir ( %d )", ARG1);
2697 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
2698}
2699
sewardje6d5e722005-06-10 10:27:55 +00002700PRE(sys_fchown)
2701{
2702 PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
2703 PRE_REG_READ3(long, "fchown",
2704 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
2705}
sewardj696c5512005-06-08 23:38:32 +00002706
2707PRE(sys_fchmod)
2708{
2709 PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
2710 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
2711}
2712
2713PRE(sys_fcntl)
2714{
2715 switch (ARG2) {
2716 // These ones ignore ARG3.
2717 case VKI_F_GETFD:
2718 case VKI_F_GETFL:
2719 case VKI_F_GETOWN:
sewardj696c5512005-06-08 23:38:32 +00002720 case VKI_F_GETSIG:
sewardj696c5512005-06-08 23:38:32 +00002721 case VKI_F_GETLEASE:
2722 PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
2723 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
2724 break;
2725
2726 // These ones use ARG3 as "arg".
2727 case VKI_F_DUPFD:
2728 case VKI_F_SETFD:
2729 case VKI_F_SETFL:
2730 case VKI_F_SETLEASE:
2731 case VKI_F_NOTIFY:
njn4ae40402005-08-24 13:55:59 +00002732 case VKI_F_SETOWN:
2733 case VKI_F_SETSIG:
sewardj696c5512005-06-08 23:38:32 +00002734 PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2735 PRE_REG_READ3(long, "fcntl",
2736 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2737 break;
2738
2739 // These ones use ARG3 as "lock".
2740 case VKI_F_GETLK:
2741 case VKI_F_SETLK:
2742 case VKI_F_SETLKW:
sewardje7aa4ae2005-06-09 12:43:42 +00002743# if defined(VGP_x86_linux)
sewardj696c5512005-06-08 23:38:32 +00002744 case VKI_F_GETLK64:
2745 case VKI_F_SETLK64:
2746 case VKI_F_SETLKW64:
2747# else
2748# endif
2749 PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2750 PRE_REG_READ3(long, "fcntl",
2751 unsigned int, fd, unsigned int, cmd,
2752 struct flock64 *, lock);
2753 break;
2754 }
2755
2756 if (ARG2 == VKI_F_SETLKW)
2757 *flags |= SfMayBlock;
2758}
2759
2760POST(sys_fcntl)
2761{
2762 vg_assert(SUCCESS);
2763 if (ARG2 == VKI_F_DUPFD) {
sewardj7eb7c582005-06-23 01:02:53 +00002764 if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
sewardj696c5512005-06-08 23:38:32 +00002765 VG_(close)(RES);
2766 SET_STATUS_Failure( VKI_EMFILE );
2767 } else {
2768 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002769 record_fd_open_named(tid, RES);
sewardj696c5512005-06-08 23:38:32 +00002770 }
2771 }
2772}
njncfb8ad52004-11-23 14:57:49 +00002773
nethercote06c7bd72004-11-14 19:11:56 +00002774// XXX: wrapper only suitable for 32-bit systems
sewardja8d8e232005-06-07 20:04:56 +00002775PRE(sys_fcntl64)
jsgf855d93d2003-10-13 22:26:55 +00002776{
njnc6168192004-11-29 13:54:10 +00002777 switch (ARG2) {
2778 // These ones ignore ARG3.
2779 case VKI_F_GETFD:
2780 case VKI_F_GETFL:
2781 case VKI_F_GETOWN:
2782 case VKI_F_SETOWN:
2783 case VKI_F_GETSIG:
2784 case VKI_F_SETSIG:
2785 case VKI_F_GETLEASE:
2786 PRINT("sys_fcntl64 ( %d, %d )", ARG1,ARG2);
2787 PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
2788 break;
2789
2790 // These ones use ARG3 as "arg".
2791 case VKI_F_DUPFD:
2792 case VKI_F_SETFD:
2793 case VKI_F_SETFL:
2794 case VKI_F_SETLEASE:
2795 case VKI_F_NOTIFY:
2796 PRINT("sys_fcntl64[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
2797 PRE_REG_READ3(long, "fcntl64",
2798 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
2799 break;
2800
2801 // These ones use ARG3 as "lock".
2802 case VKI_F_GETLK:
2803 case VKI_F_SETLK:
2804 case VKI_F_SETLKW:
sewardje7aa4ae2005-06-09 12:43:42 +00002805# if defined(VGP_x86_linux)
njnc6168192004-11-29 13:54:10 +00002806 case VKI_F_GETLK64:
2807 case VKI_F_SETLK64:
2808 case VKI_F_SETLKW64:
sewardja8d8e232005-06-07 20:04:56 +00002809# endif
njnc6168192004-11-29 13:54:10 +00002810 PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
2811 PRE_REG_READ3(long, "fcntl64",
2812 unsigned int, fd, unsigned int, cmd,
2813 struct flock64 *, lock);
2814 break;
2815 }
njncfb8ad52004-11-23 14:57:49 +00002816
sewardje7aa4ae2005-06-09 12:43:42 +00002817# if defined(VGP_x86_linux)
2818 if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
2819 *flags |= SfMayBlock;
sewardja8d8e232005-06-07 20:04:56 +00002820# else
sewardje7aa4ae2005-06-09 12:43:42 +00002821 if (ARG2 == VKI_F_SETLKW)
2822 *flags |= SfMayBlock;
sewardja8d8e232005-06-07 20:04:56 +00002823# endif
rjwalshf5f536f2003-11-17 17:45:00 +00002824}
2825
nethercote85a456f2004-11-16 17:31:56 +00002826POST(sys_fcntl64)
rjwalshf5f536f2003-11-17 17:45:00 +00002827{
sewardja8d8e232005-06-07 20:04:56 +00002828 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002829 if (ARG2 == VKI_F_DUPFD) {
sewardj7eb7c582005-06-23 01:02:53 +00002830 if (!ML_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00002831 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00002832 SET_STATUS_Failure( VKI_EMFILE );
nethercote493dd182004-02-24 23:57:47 +00002833 } else {
2834 if (VG_(clo_track_fds))
njnf845f8f2005-06-23 02:26:47 +00002835 record_fd_open_named(tid, RES);
nethercote493dd182004-02-24 23:57:47 +00002836 }
2837 }
jsgf855d93d2003-10-13 22:26:55 +00002838}
2839
sewardj696c5512005-06-08 23:38:32 +00002840PRE(sys_newfstat)
2841{
2842 PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
2843 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
2844 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
2845}
2846
2847POST(sys_newfstat)
2848{
2849 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
2850}
jsgf855d93d2003-10-13 22:26:55 +00002851
nethercote73b526f2004-10-31 18:48:21 +00002852static vki_sigset_t fork_saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00002853
nethercote75a8c982004-11-11 19:03:34 +00002854// In Linux, the sys_fork() function varies across architectures, but we
2855// ignore the various args it gets, and so it looks arch-neutral. Hmm.
sewardja8d8e232005-06-07 20:04:56 +00002856PRE(sys_fork)
jsgf855d93d2003-10-13 22:26:55 +00002857{
nethercote73b526f2004-10-31 18:48:21 +00002858 vki_sigset_t mask;
jsgf855d93d2003-10-13 22:26:55 +00002859
nethercote75a8c982004-11-11 19:03:34 +00002860 PRINT("sys_fork ( )");
2861 PRE_REG_READ0(long, "fork");
2862
jsgf855d93d2003-10-13 22:26:55 +00002863 /* Block all signals during fork, so that we can fix things up in
2864 the child without being interrupted. */
nethercote73b526f2004-10-31 18:48:21 +00002865 VG_(sigfillset)(&mask);
2866 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
jsgf855d93d2003-10-13 22:26:55 +00002867
sewardja8d8e232005-06-07 20:04:56 +00002868 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
sewardjb5f6f512005-03-10 23:59:00 +00002869
sewardja8d8e232005-06-07 20:04:56 +00002870 if (SUCCESS && RES == 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002871 VG_(do_atfork_child)(tid);
jsgf855d93d2003-10-13 22:26:55 +00002872
2873 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002874 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
sewardja8d8e232005-06-07 20:04:56 +00002875 }
2876 else
2877 if (SUCCESS && RES > 0) {
sewardjb5f6f512005-03-10 23:59:00 +00002878 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), RES);
jsgf855d93d2003-10-13 22:26:55 +00002879
jsgf855d93d2003-10-13 22:26:55 +00002880 /* restore signal mask */
nethercote73b526f2004-10-31 18:48:21 +00002881 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00002882 }
2883}
2884
sewardj8c257322005-06-08 01:01:48 +00002885PRE(sys_ftruncate)
2886{
2887 *flags |= SfMayBlock;
njn68e46592005-08-26 19:42:27 +00002888 PRINT("sys_ftruncate ( %d, %ld )", ARG1,ARG2);
sewardj8c257322005-06-08 01:01:48 +00002889 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
2890}
2891
sewardj696c5512005-06-08 23:38:32 +00002892PRE(sys_truncate)
2893{
2894 *flags |= SfMayBlock;
2895 PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
2896 PRE_REG_READ2(long, "truncate",
2897 const char *, path, unsigned long, length);
2898 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
2899}
2900
sewardje6d5e722005-06-10 10:27:55 +00002901// XXX: this wrapper is only suitable for 32-bit platforms
sewardj48db0f02005-10-07 13:30:48 +00002902#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
sewardje6d5e722005-06-10 10:27:55 +00002903PRE(sys_ftruncate64)
2904{
2905 *flags |= SfMayBlock;
2906 PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
2907 PRE_REG_READ3(long, "ftruncate64",
2908 unsigned int, fd,
2909 vki_u32, length_low32, vki_u32, length_high32);
2910}
2911#endif
2912
2913// XXX: this wrapper is only suitable for 32-bit platforms
sewardja58bbbc2006-04-14 01:04:04 +00002914#if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
sewardje6d5e722005-06-10 10:27:55 +00002915PRE(sys_truncate64)
2916{
2917 *flags |= SfMayBlock;
2918 PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
2919 PRE_REG_READ3(long, "truncate64",
2920 const char *, path,
2921 vki_u32, length_low32, vki_u32, length_high32);
2922 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
2923}
2924#endif
sewardj78b50e42005-06-08 01:47:28 +00002925
2926PRE(sys_getdents)
2927{
2928 *flags |= SfMayBlock;
2929 PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
2930 PRE_REG_READ3(long, "getdents",
2931 unsigned int, fd, struct linux_dirent *, dirp,
2932 unsigned int, count);
2933 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
2934}
2935
2936POST(sys_getdents)
2937{
2938 vg_assert(SUCCESS);
2939 if (RES > 0)
2940 POST_MEM_WRITE( ARG2, RES );
2941}
jsgf855d93d2003-10-13 22:26:55 +00002942
sewardja8d8e232005-06-07 20:04:56 +00002943PRE(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002944{
sewardj78b50e42005-06-08 01:47:28 +00002945 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00002946 PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00002947 PRE_REG_READ3(long, "getdents64",
2948 unsigned int, fd, struct linux_dirent64 *, dirp,
2949 unsigned int, count);
njn22cfccb2004-11-27 16:10:23 +00002950 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00002951}
2952
nethercote85a456f2004-11-16 17:31:56 +00002953POST(sys_getdents64)
jsgf855d93d2003-10-13 22:26:55 +00002954{
sewardja8d8e232005-06-07 20:04:56 +00002955 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002956 if (RES > 0)
2957 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00002958}
2959
sewardj78b50e42005-06-08 01:47:28 +00002960PRE(sys_getgroups)
2961{
2962 PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
2963 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
2964 if (ARG1 > 0)
2965 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
2966}
2967
2968POST(sys_getgroups)
2969{
2970 vg_assert(SUCCESS);
2971 if (ARG1 > 0 && RES > 0)
2972 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
2973}
nethercote686b5db2004-11-14 13:42:51 +00002974
sewardja8d8e232005-06-07 20:04:56 +00002975PRE(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002976{
njn4b70e8c2005-08-14 17:36:07 +00002977 // Comment from linux/fs/dcache.c:
2978 // NOTE! The user-level library version returns a character pointer.
2979 // The kernel system call just returns the length of the buffer filled
2980 // (which includes the ending '\0' character), or a negative error
2981 // value.
2982 // Is this Linux-specific? If so it should be moved to syswrap-linux.c.
njn22cfccb2004-11-27 16:10:23 +00002983 PRINT("sys_getcwd ( %p, %llu )", ARG1,(ULong)ARG2);
nethercoteac866b92004-11-15 20:23:15 +00002984 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
njn22cfccb2004-11-27 16:10:23 +00002985 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00002986}
2987
nethercote85a456f2004-11-16 17:31:56 +00002988POST(sys_getcwd)
jsgf855d93d2003-10-13 22:26:55 +00002989{
sewardja8d8e232005-06-07 20:04:56 +00002990 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00002991 if (RES != (Addr)NULL)
2992 POST_MEM_WRITE( ARG1, RES );
jsgf855d93d2003-10-13 22:26:55 +00002993}
2994
sewardja8d8e232005-06-07 20:04:56 +00002995PRE(sys_geteuid)
jsgf855d93d2003-10-13 22:26:55 +00002996{
nethercote0df495a2004-11-11 16:38:21 +00002997 PRINT("sys_geteuid ( )");
2998 PRE_REG_READ0(long, "geteuid");
jsgf855d93d2003-10-13 22:26:55 +00002999}
3000
sewardj78b50e42005-06-08 01:47:28 +00003001PRE(sys_getegid)
3002{
3003 PRINT("sys_getegid ( )");
3004 PRE_REG_READ0(long, "getegid");
3005}
3006
sewardj78b50e42005-06-08 01:47:28 +00003007PRE(sys_getgid)
3008{
3009 PRINT("sys_getgid ( )");
3010 PRE_REG_READ0(long, "getgid");
3011}
jsgf855d93d2003-10-13 22:26:55 +00003012
sewardja8d8e232005-06-07 20:04:56 +00003013PRE(sys_getpid)
jsgf855d93d2003-10-13 22:26:55 +00003014{
nethercote4e632c22004-11-09 16:45:33 +00003015 PRINT("sys_getpid ()");
3016 PRE_REG_READ0(long, "getpid");
jsgf855d93d2003-10-13 22:26:55 +00003017}
3018
sewardj696c5512005-06-08 23:38:32 +00003019PRE(sys_getpgid)
3020{
3021 PRINT("sys_getpgid ( %d )", ARG1);
3022 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
3023}
sewardj78b50e42005-06-08 01:47:28 +00003024
3025PRE(sys_getpgrp)
3026{
3027 PRINT("sys_getpgrp ()");
3028 PRE_REG_READ0(long, "getpgrp");
3029}
jsgf855d93d2003-10-13 22:26:55 +00003030
sewardja8d8e232005-06-07 20:04:56 +00003031PRE(sys_getppid)
jsgf855d93d2003-10-13 22:26:55 +00003032{
nethercote4e632c22004-11-09 16:45:33 +00003033 PRINT("sys_getppid ()");
3034 PRE_REG_READ0(long, "getppid");
jsgf855d93d2003-10-13 22:26:55 +00003035}
3036
njncf45fd42004-11-24 16:30:22 +00003037static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
jsgf855d93d2003-10-13 22:26:55 +00003038{
nethercote620154f2004-11-12 21:21:07 +00003039 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
jsgf855d93d2003-10-13 22:26:55 +00003040
nethercote620154f2004-11-12 21:21:07 +00003041 switch (a1) {
3042 case VKI_RLIMIT_NOFILE:
3043 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
3044 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
3045 break;
nethercote535f03b2004-02-15 15:32:51 +00003046
nethercote620154f2004-11-12 21:21:07 +00003047 case VKI_RLIMIT_DATA:
3048 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
3049 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00003050
nethercote620154f2004-11-12 21:21:07 +00003051 case VKI_RLIMIT_STACK:
3052 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
3053 break;
fitzhardingeb50068f2004-02-24 23:42:55 +00003054 }
jsgf855d93d2003-10-13 22:26:55 +00003055}
3056
sewardj696c5512005-06-08 23:38:32 +00003057PRE(sys_old_getrlimit)
3058{
3059 PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
3060 PRE_REG_READ2(long, "old_getrlimit",
3061 unsigned int, resource, struct rlimit *, rlim);
3062 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
3063}
3064
3065POST(sys_old_getrlimit)
3066{
3067 common_post_getrlimit(tid, ARG1, ARG2);
3068}
nethercote620154f2004-11-12 21:21:07 +00003069
sewardja8d8e232005-06-07 20:04:56 +00003070PRE(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00003071{
njn22cfccb2004-11-27 16:10:23 +00003072 PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
nethercote620154f2004-11-12 21:21:07 +00003073 PRE_REG_READ2(long, "getrlimit",
3074 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00003075 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
nethercote620154f2004-11-12 21:21:07 +00003076}
3077
nethercote85a456f2004-11-16 17:31:56 +00003078POST(sys_getrlimit)
nethercote620154f2004-11-12 21:21:07 +00003079{
njn22cfccb2004-11-27 16:10:23 +00003080 common_post_getrlimit(tid, ARG1, ARG2);
nethercote620154f2004-11-12 21:21:07 +00003081}
jsgf855d93d2003-10-13 22:26:55 +00003082
sewardj696c5512005-06-08 23:38:32 +00003083PRE(sys_getrusage)
3084{
sewardj696c5512005-06-08 23:38:32 +00003085 PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
3086 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
3087 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
3088}
3089
3090POST(sys_getrusage)
3091{
3092 vg_assert(SUCCESS);
3093 if (RES == 0)
3094 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
3095}
jsgf855d93d2003-10-13 22:26:55 +00003096
sewardja8d8e232005-06-07 20:04:56 +00003097PRE(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00003098{
njn22cfccb2004-11-27 16:10:23 +00003099 PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
nethercote686b5db2004-11-14 13:42:51 +00003100 PRE_REG_READ2(long, "gettimeofday",
3101 struct timeval *, tv, struct timezone *, tz);
njn22cfccb2004-11-27 16:10:23 +00003102 PRE_MEM_WRITE( "gettimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3103 if (ARG2 != 0)
3104 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003105}
3106
nethercote85a456f2004-11-16 17:31:56 +00003107POST(sys_gettimeofday)
jsgf855d93d2003-10-13 22:26:55 +00003108{
sewardja8d8e232005-06-07 20:04:56 +00003109 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00003110 if (RES == 0) {
3111 POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
3112 if (ARG2 != 0)
3113 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
jsgf855d93d2003-10-13 22:26:55 +00003114 }
3115}
3116
sewardj696c5512005-06-08 23:38:32 +00003117PRE(sys_settimeofday)
3118{
3119 PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
3120 PRE_REG_READ2(long, "settimeofday",
3121 struct timeval *, tv, struct timezone *, tz);
3122 PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
3123 if (ARG2 != 0) {
3124 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3125 /* maybe should warn if tz->tz_dsttime is non-zero? */
3126 }
3127}
nethercote686b5db2004-11-14 13:42:51 +00003128
sewardja8d8e232005-06-07 20:04:56 +00003129PRE(sys_getuid)
jsgf855d93d2003-10-13 22:26:55 +00003130{
nethercote0df495a2004-11-11 16:38:21 +00003131 PRINT("sys_getuid ( )");
3132 PRE_REG_READ0(long, "getuid");
jsgf855d93d2003-10-13 22:26:55 +00003133}
3134
nethercote2e1c37d2004-11-13 13:57:12 +00003135// XXX: I reckon some of these cases must be x86-specific
sewardja8d8e232005-06-07 20:04:56 +00003136PRE(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00003137{
sewardja8d8e232005-06-07 20:04:56 +00003138 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00003139 PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
nethercote9c311eb2004-11-12 18:20:12 +00003140 PRE_REG_READ3(long, "ioctl",
3141 unsigned int, fd, unsigned int, request, unsigned long, arg);
3142
njn22cfccb2004-11-27 16:10:23 +00003143 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00003144 case VKI_TCSETS:
3145 case VKI_TCSETSW:
3146 case VKI_TCSETSF:
njn22cfccb2004-11-27 16:10:23 +00003147 PRE_MEM_READ( "ioctl(TCSET{S,SW,SF})", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003148 break;
nethercote73b526f2004-10-31 18:48:21 +00003149 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00003150 PRE_MEM_WRITE( "ioctl(TCGETS)", ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00003151 break;
nethercote73b526f2004-10-31 18:48:21 +00003152 case VKI_TCSETA:
3153 case VKI_TCSETAW:
3154 case VKI_TCSETAF:
njn22cfccb2004-11-27 16:10:23 +00003155 PRE_MEM_READ( "ioctl(TCSET{A,AW,AF})", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003156 break;
nethercote73b526f2004-10-31 18:48:21 +00003157 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00003158 PRE_MEM_WRITE( "ioctl(TCGETA)", ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00003159 break;
nethercote73b526f2004-10-31 18:48:21 +00003160 case VKI_TCSBRK:
3161 case VKI_TCXONC:
3162 case VKI_TCSBRKP:
3163 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00003164 /* These just take an int by value */
3165 break;
nethercote73b526f2004-10-31 18:48:21 +00003166 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003167 PRE_MEM_WRITE( "ioctl(TIOCGWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003168 break;
nethercote73b526f2004-10-31 18:48:21 +00003169 case VKI_TIOCSWINSZ:
njn22cfccb2004-11-27 16:10:23 +00003170 PRE_MEM_READ( "ioctl(TIOCSWINSZ)", ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00003171 break;
nethercote73b526f2004-10-31 18:48:21 +00003172 case VKI_TIOCMBIS:
njn22cfccb2004-11-27 16:10:23 +00003173 PRE_MEM_READ( "ioctl(TIOCMBIS)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003174 break;
nethercote73b526f2004-10-31 18:48:21 +00003175 case VKI_TIOCMBIC:
njn22cfccb2004-11-27 16:10:23 +00003176 PRE_MEM_READ( "ioctl(TIOCMBIC)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003177 break;
nethercote73b526f2004-10-31 18:48:21 +00003178 case VKI_TIOCMSET:
njn22cfccb2004-11-27 16:10:23 +00003179 PRE_MEM_READ( "ioctl(TIOCMSET)", ARG3, sizeof(unsigned int) );
thughesfc5cd002004-09-11 14:37:04 +00003180 break;
tom62ba7582005-07-28 16:26:34 +00003181 case VKI_TIOCMGET:
3182 PRE_MEM_WRITE( "ioctl(TIOCMGET)", ARG3, sizeof(unsigned int) );
3183 break;
nethercote73b526f2004-10-31 18:48:21 +00003184 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00003185 PRE_MEM_READ( "ioctl(TIOCLINUX)", ARG3, sizeof(char *) );
3186 if (*(char *)ARG3 == 11) {
3187 PRE_MEM_READ( "ioctl(TIOCLINUX, 11)", ARG3, 2 * sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00003188 }
3189 break;
nethercote73b526f2004-10-31 18:48:21 +00003190 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003191 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00003192 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003193 break;
nethercote73b526f2004-10-31 18:48:21 +00003194 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00003195 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00003196 PRE_MEM_WRITE( "ioctl(TIOCGPGRP)", ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00003197 break;
nethercote73b526f2004-10-31 18:48:21 +00003198 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00003199 PRE_MEM_WRITE( "ioctl(TIOCGPTN)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003200 break;
nethercote73b526f2004-10-31 18:48:21 +00003201 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00003202 /* Just takes an int value. */
3203 break;
nethercote73b526f2004-10-31 18:48:21 +00003204 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
njn22cfccb2004-11-27 16:10:23 +00003205 PRE_MEM_READ( "ioctl(TIOCSPTLCK)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003206 break;
nethercote73b526f2004-10-31 18:48:21 +00003207 case VKI_FIONBIO:
njn22cfccb2004-11-27 16:10:23 +00003208 PRE_MEM_READ( "ioctl(FIONBIO)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003209 break;
nethercote73b526f2004-10-31 18:48:21 +00003210 case VKI_FIOASYNC:
njn22cfccb2004-11-27 16:10:23 +00003211 PRE_MEM_READ( "ioctl(FIOASYNC)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003212 break;
nethercote73b526f2004-10-31 18:48:21 +00003213 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00003214 PRE_MEM_WRITE( "ioctl(FIONREAD)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003215 break;
3216
tom5d2af672006-02-11 13:29:09 +00003217 case VKI_TIOCSERGETLSR:
3218 PRE_MEM_WRITE( "ioctl(TIOCSERGETLSR)", ARG3, sizeof(int) );
3219 break;
3220 case VKI_TIOCGICOUNT:
3221 PRE_MEM_WRITE( "ioctl(TIOCGICOUNT)", ARG3,
3222 sizeof(struct vki_serial_icounter_struct) );
3223 break;
3224
nethercote73b526f2004-10-31 18:48:21 +00003225 case VKI_SG_SET_COMMAND_Q:
njn22cfccb2004-11-27 16:10:23 +00003226 PRE_MEM_READ( "ioctl(SG_SET_COMMAND_Q)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003227 break;
nethercote73b526f2004-10-31 18:48:21 +00003228 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00003229 PRE_MEM_WRITE( "ioctl(SG_IO)", ARG3, sizeof(vki_sg_io_hdr_t) );
jsgf855d93d2003-10-13 22:26:55 +00003230 break;
nethercote73b526f2004-10-31 18:48:21 +00003231 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00003232 PRE_MEM_WRITE( "ioctl(SG_GET_SCSI_ID)", ARG3, sizeof(vki_sg_scsi_id_t) );
jsgf855d93d2003-10-13 22:26:55 +00003233 break;
nethercote73b526f2004-10-31 18:48:21 +00003234 case VKI_SG_SET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003235 PRE_MEM_READ( "ioctl(SG_SET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003236 break;
nethercote73b526f2004-10-31 18:48:21 +00003237 case VKI_SG_SET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003238 PRE_MEM_READ( "ioctl(SG_SET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003239 break;
nethercote73b526f2004-10-31 18:48:21 +00003240 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00003241 PRE_MEM_WRITE( "ioctl(SG_GET_RESERVED_SIZE)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003242 break;
nethercote73b526f2004-10-31 18:48:21 +00003243 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00003244 PRE_MEM_WRITE( "ioctl(SG_GET_TIMEOUT)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003245 break;
nethercote73b526f2004-10-31 18:48:21 +00003246 case VKI_SG_GET_VERSION_NUM:
njn22cfccb2004-11-27 16:10:23 +00003247 PRE_MEM_READ( "ioctl(SG_GET_VERSION_NUM)", ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00003248 break;
nethercote73b526f2004-10-31 18:48:21 +00003249 case VKI_SG_EMULATED_HOST: /* 0x2203 */
njn22cfccb2004-11-27 16:10:23 +00003250 PRE_MEM_WRITE( "ioctl(SG_EMULATED_HOST)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003251 break;
nethercote73b526f2004-10-31 18:48:21 +00003252 case VKI_SG_GET_SG_TABLESIZE: /* 0x227f */
njn22cfccb2004-11-27 16:10:23 +00003253 PRE_MEM_WRITE( "ioctl(SG_GET_SG_TABLESIZE)", ARG3, sizeof(int) );
thughes5b788fb2004-09-11 15:07:14 +00003254 break;
jsgf855d93d2003-10-13 22:26:55 +00003255
muellera4b153a2003-11-19 22:07:14 +00003256 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00003257 PRE_MEM_WRITE( "ioctl(IIOCGETCPS)", ARG3,
nethercote95a97862004-11-06 16:31:43 +00003258 VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00003259 break;
muellera4b153a2003-11-19 22:07:14 +00003260 case VKI_IIOCNETGPN:
nethercoteef0c7662004-11-06 15:38:43 +00003261 PRE_MEM_READ( "ioctl(IIOCNETGPN)",
njn22cfccb2004-11-27 16:10:23 +00003262 (Addr)&((vki_isdn_net_ioctl_phone *)ARG3)->name,
3263 sizeof(((vki_isdn_net_ioctl_phone *)ARG3)->name) );
3264 PRE_MEM_WRITE( "ioctl(IIOCNETGPN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003265 sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00003266 break;
3267
3268 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00003269 case VKI_SIOCGIFINDEX: /* get iface index */
nethercoteef0c7662004-11-06 15:38:43 +00003270 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFINDEX)",
njn22cfccb2004-11-27 16:10:23 +00003271 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3272 PRE_MEM_WRITE( "ioctl(SIOCGIFINDEX)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003273 break;
nethercote73b526f2004-10-31 18:48:21 +00003274 case VKI_SIOCGIFFLAGS: /* get flags */
nethercoteef0c7662004-11-06 15:38:43 +00003275 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003276 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3277 PRE_MEM_WRITE( "ioctl(SIOCGIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003278 break;
nethercote73b526f2004-10-31 18:48:21 +00003279 case VKI_SIOCGIFHWADDR: /* Get hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003280 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003281 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3282 PRE_MEM_WRITE( "ioctl(SIOCGIFHWADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003283 break;
nethercote73b526f2004-10-31 18:48:21 +00003284 case VKI_SIOCGIFMTU: /* get MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003285 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003286 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3287 PRE_MEM_WRITE( "ioctl(SIOCGIFMTU)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003288 break;
nethercote73b526f2004-10-31 18:48:21 +00003289 case VKI_SIOCGIFADDR: /* get PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003290 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFADDR)",
njn22cfccb2004-11-27 16:10:23 +00003291 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3292 PRE_MEM_WRITE( "ioctl(SIOCGIFADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003293 break;
nethercote73b526f2004-10-31 18:48:21 +00003294 case VKI_SIOCGIFNETMASK: /* get network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003295 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFNETMASK)",
njn22cfccb2004-11-27 16:10:23 +00003296 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3297 PRE_MEM_WRITE( "ioctl(SIOCGIFNETMASK)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003298 break;
nethercote73b526f2004-10-31 18:48:21 +00003299 case VKI_SIOCGIFMETRIC: /* get metric */
nethercoteef0c7662004-11-06 15:38:43 +00003300 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003301 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3302 PRE_MEM_WRITE( "ioctl(SIOCGIFMETRIC)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003303 break;
nethercote73b526f2004-10-31 18:48:21 +00003304 case VKI_SIOCGIFMAP: /* Get device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003305 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003306 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3307 PRE_MEM_WRITE( "ioctl(SIOCGIFMAP)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003308 break;
nethercote73b526f2004-10-31 18:48:21 +00003309 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003310 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003311 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3312 PRE_MEM_WRITE( "ioctl(SIOCGIFTXQLEN)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003313 break;
nethercote73b526f2004-10-31 18:48:21 +00003314 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003315 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFDSTADDR)",
njn22cfccb2004-11-27 16:10:23 +00003316 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3317 PRE_MEM_WRITE( "ioctl(SIOCGIFDSTADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003318 break;
nethercote73b526f2004-10-31 18:48:21 +00003319 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
nethercoteef0c7662004-11-06 15:38:43 +00003320 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFBRDADDR)",
njn22cfccb2004-11-27 16:10:23 +00003321 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3322 PRE_MEM_WRITE( "ioctl(SIOCGIFBRDADDR)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003323 break;
nethercote73b526f2004-10-31 18:48:21 +00003324 case VKI_SIOCGIFNAME: /* get iface name */
nethercoteef0c7662004-11-06 15:38:43 +00003325 PRE_MEM_READ( "ioctl(SIOCGIFNAME)",
tom3b86ae52005-07-29 18:42:22 +00003326 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
njn22cfccb2004-11-27 16:10:23 +00003327 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
3328 PRE_MEM_WRITE( "ioctl(SIOCGIFNAME)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003329 break;
nethercote73b526f2004-10-31 18:48:21 +00003330 case VKI_SIOCGMIIPHY: /* get hardware entry */
nethercoteef0c7662004-11-06 15:38:43 +00003331 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIPHY)",
njn22cfccb2004-11-27 16:10:23 +00003332 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
3333 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIPHY)", ARG3, sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003334 break;
nethercote73b526f2004-10-31 18:48:21 +00003335 case VKI_SIOCGMIIREG: /* get hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003336 PRE_MEM_RASCIIZ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003337 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003338 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003339 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3340 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003341 PRE_MEM_READ( "ioctl(SIOCGIFMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003342 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3343 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
3344 PRE_MEM_WRITE( "ioctl(SIOCGIFMIIREG)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003345 sizeof(struct vki_ifreq));
thughesbe811712004-06-17 23:04:58 +00003346 break;
nethercote73b526f2004-10-31 18:48:21 +00003347 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00003348 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00003349 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
3350 KERNEL_DO_SYSCALL(tid,RES);
3351 if (!VG_(is_kerror)(RES) && RES == 0)
3352 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00003353 */
tomb9fef192005-07-18 22:45:55 +00003354 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
3355 (Addr)&((struct vki_ifconf *)ARG3)->ifc_len,
3356 sizeof(((struct vki_ifconf *)ARG3)->ifc_len));
3357 PRE_MEM_READ( "ioctl(SIOCGIFCONF)",
3358 (Addr)&((struct vki_ifconf *)ARG3)->vki_ifc_buf,
3359 sizeof(((struct vki_ifconf *)ARG3)->vki_ifc_buf));
njn22cfccb2004-11-27 16:10:23 +00003360 if ( ARG3 ) {
jsgf855d93d2003-10-13 22:26:55 +00003361 // TODO len must be readable and writable
3362 // buf pointer only needs to be readable
njn22cfccb2004-11-27 16:10:23 +00003363 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003364 PRE_MEM_WRITE( "ioctl(SIOCGIFCONF).ifc_buf",
nethercote50397c22004-11-04 18:03:06 +00003365 (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00003366 }
3367 break;
nethercote73b526f2004-10-31 18:48:21 +00003368 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00003369 PRE_MEM_WRITE( "ioctl(SIOCGSTAMP)", ARG3, sizeof(struct vki_timeval));
jsgf855d93d2003-10-13 22:26:55 +00003370 break;
3371 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
3372 the number of bytes currently in that socket's send buffer.
3373 It writes this value as an int to the memory location
3374 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00003375 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00003376 PRE_MEM_WRITE( "ioctl(SIOCOUTQ)", ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003377 break;
nethercote73b526f2004-10-31 18:48:21 +00003378 case VKI_SIOCGRARP: /* get RARP table entry */
3379 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003380 PRE_MEM_WRITE( "ioctl(SIOCGARP)", ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00003381 break;
3382
nethercote73b526f2004-10-31 18:48:21 +00003383 case VKI_SIOCSIFFLAGS: /* set flags */
nethercoteef0c7662004-11-06 15:38:43 +00003384 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003385 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003386 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)",
njn22cfccb2004-11-27 16:10:23 +00003387 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
3388 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00003389 break;
nethercote73b526f2004-10-31 18:48:21 +00003390 case VKI_SIOCSIFMAP: /* Set device parameters */
nethercoteef0c7662004-11-06 15:38:43 +00003391 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003392 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003393 PRE_MEM_READ( "ioctl(SIOCSIFMAP)",
njn22cfccb2004-11-27 16:10:23 +00003394 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
3395 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00003396 break;
nethercote73b526f2004-10-31 18:48:21 +00003397 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
nethercoteef0c7662004-11-06 15:38:43 +00003398 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003399 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003400 PRE_MEM_READ( "ioctl(SIOCSIFTXQLEN)",
njn22cfccb2004-11-27 16:10:23 +00003401 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
3402 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00003403 break;
nethercote73b526f2004-10-31 18:48:21 +00003404 case VKI_SIOCSIFADDR: /* set PA address */
3405 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
3406 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
3407 case VKI_SIOCSIFNETMASK: /* set network PA mask */
nethercoteef0c7662004-11-06 15:38:43 +00003408 PRE_MEM_RASCIIZ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003409 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003410 PRE_MEM_READ( "ioctl(SIOCSIF*ADDR)",
njn22cfccb2004-11-27 16:10:23 +00003411 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
3412 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
jsgf855d93d2003-10-13 22:26:55 +00003413 break;
nethercote73b526f2004-10-31 18:48:21 +00003414 case VKI_SIOCSIFMETRIC: /* set metric */
nethercoteef0c7662004-11-06 15:38:43 +00003415 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003416 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003417 PRE_MEM_READ( "ioctl(SIOCSIFMETRIC)",
njn22cfccb2004-11-27 16:10:23 +00003418 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
3419 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00003420 break;
nethercote73b526f2004-10-31 18:48:21 +00003421 case VKI_SIOCSIFMTU: /* set MTU size */
nethercoteef0c7662004-11-06 15:38:43 +00003422 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003423 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003424 PRE_MEM_READ( "ioctl(SIOCSIFMTU)",
njn22cfccb2004-11-27 16:10:23 +00003425 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
3426 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00003427 break;
nethercote73b526f2004-10-31 18:48:21 +00003428 case VKI_SIOCSIFHWADDR: /* set hardware address */
nethercoteef0c7662004-11-06 15:38:43 +00003429 PRE_MEM_RASCIIZ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003430 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003431 PRE_MEM_READ( "ioctl(SIOCSIFHWADDR)",
njn22cfccb2004-11-27 16:10:23 +00003432 (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
3433 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00003434 break;
nethercote73b526f2004-10-31 18:48:21 +00003435 case VKI_SIOCSMIIREG: /* set hardware entry registers */
nethercoteef0c7662004-11-06 15:38:43 +00003436 PRE_MEM_RASCIIZ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003437 (Addr)((struct vki_ifreq *)ARG3)->vki_ifr_name );
nethercoteef0c7662004-11-06 15:38:43 +00003438 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003439 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
3440 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
nethercoteef0c7662004-11-06 15:38:43 +00003441 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003442 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num,
3443 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->reg_num) );
nethercoteef0c7662004-11-06 15:38:43 +00003444 PRE_MEM_READ( "ioctl(SIOCSMIIREG)",
njn22cfccb2004-11-27 16:10:23 +00003445 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in,
3446 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_in) );
thughesbe811712004-06-17 23:04:58 +00003447 break;
jsgf855d93d2003-10-13 22:26:55 +00003448 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00003449 case VKI_SIOCADDRT: /* add routing table entry */
3450 case VKI_SIOCDELRT: /* delete routing table entry */
njn22cfccb2004-11-27 16:10:23 +00003451 PRE_MEM_READ( "ioctl(SIOCADDRT/DELRT)", ARG3,
nethercoteef0c7662004-11-06 15:38:43 +00003452 sizeof(struct vki_rtentry));
jsgf855d93d2003-10-13 22:26:55 +00003453 break;
3454
3455 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003456 case VKI_SIOCDRARP: /* delete RARP table entry */
3457 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00003458 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00003459 case VKI_SIOCSARP: /* set ARP table entry */
3460 case VKI_SIOCDARP: /* delete ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00003461 PRE_MEM_READ( "ioctl(SIOCSIFFLAGS)", ARG3, sizeof(struct vki_ifreq));
jsgf855d93d2003-10-13 22:26:55 +00003462 break;
3463
nethercote73b526f2004-10-31 18:48:21 +00003464 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00003465 PRE_MEM_WRITE( "ioctl(SIOCGPGRP)", ARG3, sizeof(int) );
thughes1174fed2004-09-11 15:33:17 +00003466 break;
nethercote73b526f2004-10-31 18:48:21 +00003467 case VKI_SIOCSPGRP:
njn22cfccb2004-11-27 16:10:23 +00003468 PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
sewardja8d8e232005-06-07 20:04:56 +00003469 //tst->sys_flags &= ~SfMayBlock;
jsgf855d93d2003-10-13 22:26:55 +00003470 break;
3471
3472 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00003473 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
3474 case VKI_SNDCTL_SEQ_GETINCOUNT:
3475 case VKI_SNDCTL_SEQ_PERCMODE:
3476 case VKI_SNDCTL_SEQ_TESTMIDI:
3477 case VKI_SNDCTL_SEQ_RESETSAMPLES:
3478 case VKI_SNDCTL_SEQ_NRSYNTHS:
3479 case VKI_SNDCTL_SEQ_NRMIDIS:
3480 case VKI_SNDCTL_SEQ_GETTIME:
3481 case VKI_SNDCTL_DSP_GETFMTS:
3482 case VKI_SNDCTL_DSP_GETTRIGGER:
3483 case VKI_SNDCTL_DSP_GETODELAY:
nethercote73b526f2004-10-31 18:48:21 +00003484 case VKI_SNDCTL_DSP_GETSPDIF:
nethercote73b526f2004-10-31 18:48:21 +00003485 case VKI_SNDCTL_DSP_GETCAPS:
3486 case VKI_SOUND_PCM_READ_RATE:
3487 case VKI_SOUND_PCM_READ_CHANNELS:
3488 case VKI_SOUND_PCM_READ_BITS:
sewardj2c48c7b2005-11-29 13:05:56 +00003489#if !defined(VGA_ppc32) && !defined(VGA_ppc64)
nethercote73b526f2004-10-31 18:48:21 +00003490 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
cerion85665ca2005-06-20 15:51:07 +00003491#endif
nethercote73b526f2004-10-31 18:48:21 +00003492 case VKI_SOUND_PCM_READ_FILTER:
nethercoteef0c7662004-11-06 15:38:43 +00003493 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, int))",
njn22cfccb2004-11-27 16:10:23 +00003494 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003495 break;
nethercote73b526f2004-10-31 18:48:21 +00003496 case VKI_SNDCTL_SEQ_CTRLRATE:
3497 case VKI_SNDCTL_DSP_SPEED:
3498 case VKI_SNDCTL_DSP_STEREO:
3499 case VKI_SNDCTL_DSP_GETBLKSIZE:
3500 case VKI_SNDCTL_DSP_CHANNELS:
3501 case VKI_SOUND_PCM_WRITE_FILTER:
3502 case VKI_SNDCTL_DSP_SUBDIVIDE:
3503 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00003504 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00003505 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00003506 case VKI_SNDCTL_TMR_TIMEBASE:
3507 case VKI_SNDCTL_TMR_TEMPO:
3508 case VKI_SNDCTL_TMR_SOURCE:
3509 case VKI_SNDCTL_MIDI_PRETIME:
3510 case VKI_SNDCTL_MIDI_MPUMODE:
nethercoteef0c7662004-11-06 15:38:43 +00003511 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003512 ARG3, sizeof(int));
nethercoteef0c7662004-11-06 15:38:43 +00003513 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOWR, int))",
njn22cfccb2004-11-27 16:10:23 +00003514 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003515 break;
nethercote73b526f2004-10-31 18:48:21 +00003516 case VKI_SNDCTL_DSP_GETOSPACE:
3517 case VKI_SNDCTL_DSP_GETISPACE:
nethercoteef0c7662004-11-06 15:38:43 +00003518 PRE_MEM_WRITE( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOR, audio_buf_info))",
njn22cfccb2004-11-27 16:10:23 +00003519 ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00003520 break;
nethercote73b526f2004-10-31 18:48:21 +00003521 case VKI_SNDCTL_DSP_SETTRIGGER:
nethercoteef0c7662004-11-06 15:38:43 +00003522 PRE_MEM_READ( "ioctl(SNDCTL_XXX|SOUND_XXX (SIOW, int))",
njn22cfccb2004-11-27 16:10:23 +00003523 ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00003524 break;
3525
nethercote73b526f2004-10-31 18:48:21 +00003526 case VKI_SNDCTL_DSP_POST:
3527 case VKI_SNDCTL_DSP_RESET:
3528 case VKI_SNDCTL_DSP_SYNC:
3529 case VKI_SNDCTL_DSP_SETSYNCRO:
3530 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00003531 break;
3532
tom2f932882005-11-14 17:03:54 +00003533 /* linux/soundcard interface (ALSA) */
3534 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
3535 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
3536 case VKI_SNDRV_PCM_IOCTL_PREPARE:
3537 case VKI_SNDRV_PCM_IOCTL_RESET:
3538 case VKI_SNDRV_PCM_IOCTL_START:
3539 case VKI_SNDRV_PCM_IOCTL_DROP:
3540 case VKI_SNDRV_PCM_IOCTL_DRAIN:
3541 case VKI_SNDRV_PCM_IOCTL_RESUME:
3542 case VKI_SNDRV_PCM_IOCTL_XRUN:
3543 case VKI_SNDRV_PCM_IOCTL_UNLINK:
3544 case VKI_SNDRV_TIMER_IOCTL_START:
3545 case VKI_SNDRV_TIMER_IOCTL_STOP:
3546 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
3547 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
3548 break;
3549
jsgf855d93d2003-10-13 22:26:55 +00003550 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00003551 case VKI_RTC_UIE_ON:
3552 case VKI_RTC_UIE_OFF:
3553 case VKI_RTC_AIE_ON:
3554 case VKI_RTC_AIE_OFF:
3555 case VKI_RTC_PIE_ON:
3556 case VKI_RTC_PIE_OFF:
3557 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00003558 break;
nethercote73b526f2004-10-31 18:48:21 +00003559 case VKI_RTC_RD_TIME:
3560 case VKI_RTC_ALM_READ:
nethercoteef0c7662004-11-06 15:38:43 +00003561 PRE_MEM_WRITE( "ioctl(RTC_RD_TIME/ALM_READ)",
njn22cfccb2004-11-27 16:10:23 +00003562 ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003563 break;
nethercote73b526f2004-10-31 18:48:21 +00003564 case VKI_RTC_ALM_SET:
njn22cfccb2004-11-27 16:10:23 +00003565 PRE_MEM_READ( "ioctl(RTC_ALM_SET)", ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00003566 break;
nethercote73b526f2004-10-31 18:48:21 +00003567 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00003568 PRE_MEM_WRITE( "ioctl(RTC_IRQP_READ)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003569 break;
jsgf855d93d2003-10-13 22:26:55 +00003570
tomeafc49b2005-07-28 16:08:09 +00003571 /* Block devices */
3572 case VKI_BLKROSET:
3573 PRE_MEM_READ( "ioctl(BLKROSET)", ARG3, sizeof(int));
3574 break;
3575 case VKI_BLKROGET:
3576 PRE_MEM_WRITE( "ioctl(BLKROGET)", ARG3, sizeof(int));
3577 break;
nethercote95a97862004-11-06 16:31:43 +00003578 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00003579 PRE_MEM_WRITE( "ioctl(BLKGETSIZE)", ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00003580 break;
tomeafc49b2005-07-28 16:08:09 +00003581 case VKI_BLKRASET:
3582 break;
3583 case VKI_BLKRAGET:
3584 PRE_MEM_WRITE( "ioctl(BLKRAGET)", ARG3, sizeof(long));
3585 break;
3586 case VKI_BLKFRASET:
3587 break;
3588 case VKI_BLKFRAGET:
3589 PRE_MEM_WRITE( "ioctl(BLKFRAGET)", ARG3, sizeof(long));
3590 break;
3591 case VKI_BLKSECTGET:
3592 PRE_MEM_WRITE( "ioctl(BLKSECTGET)", ARG3, sizeof(unsigned short));
3593 break;
3594 case VKI_BLKSSZGET:
3595 PRE_MEM_WRITE( "ioctl(BLKSSZGET)", ARG3, sizeof(int));
3596 break;
3597 case VKI_BLKBSZGET:
3598 PRE_MEM_WRITE( "ioctl(BLKBSZGET)", ARG3, sizeof(int));
3599 break;
3600 case VKI_BLKBSZSET:
3601 PRE_MEM_READ( "ioctl(BLKBSZSET)", ARG3, sizeof(int));
3602 break;
tomd6555642005-07-18 13:26:55 +00003603 case VKI_BLKGETSIZE64:
3604 PRE_MEM_WRITE( "ioctl(BLKGETSIZE64)", ARG3, sizeof(unsigned long long));
3605 break;
jsgf855d93d2003-10-13 22:26:55 +00003606
thughesacbbc322004-06-19 12:12:01 +00003607 /* Hard disks */
tom2c2bc252005-07-28 16:13:42 +00003608 case VKI_HDIO_GETGEO: /* 0x0301 */
3609 PRE_MEM_WRITE( "ioctl(HDIO_GETGEO)", ARG3, sizeof(struct vki_hd_geometry));
3610 break;
tom5d2af672006-02-11 13:29:09 +00003611 case VKI_HDIO_GET_DMA: /* 0x030b */
3612 PRE_MEM_WRITE( "ioctl(HDIO_GET_DMA)", ARG3, sizeof(long));
3613 break;
nethercote73b526f2004-10-31 18:48:21 +00003614 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00003615 PRE_MEM_WRITE( "ioctl(HDIO_GET_IDENTITY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003616 VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00003617 break;
3618
jsgf855d93d2003-10-13 22:26:55 +00003619 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00003620 case VKI_CDROM_GET_MCN:
njn22cfccb2004-11-27 16:10:23 +00003621 PRE_MEM_READ( "ioctl(CDROM_GET_MCN)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003622 sizeof(struct vki_cdrom_mcn) );
nethercote671398c2004-02-22 18:08:04 +00003623 break;
nethercote73b526f2004-10-31 18:48:21 +00003624 case VKI_CDROM_SEND_PACKET:
njn22cfccb2004-11-27 16:10:23 +00003625 PRE_MEM_READ( "ioctl(CDROM_SEND_PACKET)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003626 sizeof(struct vki_cdrom_generic_command));
nethercote671398c2004-02-22 18:08:04 +00003627 break;
nethercote73b526f2004-10-31 18:48:21 +00003628 case VKI_CDROMSUBCHNL:
nethercote11e07d32004-11-06 16:17:52 +00003629 PRE_MEM_READ( "ioctl(CDROMSUBCHNL (cdsc_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003630 (Addr) &(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format),
3631 sizeof(((struct vki_cdrom_subchnl*) ARG3)->cdsc_format));
3632 PRE_MEM_WRITE( "ioctl(CDROMSUBCHNL)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003633 sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00003634 break;
nethercote73b526f2004-10-31 18:48:21 +00003635 case VKI_CDROMREADMODE2:
njn22cfccb2004-11-27 16:10:23 +00003636 PRE_MEM_READ( "ioctl(CDROMREADMODE2)", ARG3, VKI_CD_FRAMESIZE_RAW0 );
nethercote671398c2004-02-22 18:08:04 +00003637 break;
nethercote73b526f2004-10-31 18:48:21 +00003638 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00003639 PRE_MEM_WRITE( "ioctl(CDROMREADTOCHDR)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003640 sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00003641 break;
nethercote73b526f2004-10-31 18:48:21 +00003642 case VKI_CDROMREADTOCENTRY:
nethercote11e07d32004-11-06 16:17:52 +00003643 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_format, char))",
njn22cfccb2004-11-27 16:10:23 +00003644 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_format),
3645 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_format));
nethercote11e07d32004-11-06 16:17:52 +00003646 PRE_MEM_READ( "ioctl(CDROMREADTOCENTRY (cdte_track, char))",
njn22cfccb2004-11-27 16:10:23 +00003647 (Addr) &(((struct vki_cdrom_tocentry*) ARG3)->cdte_track),
3648 sizeof(((struct vki_cdrom_tocentry*) ARG3)->cdte_track));
3649 PRE_MEM_WRITE( "ioctl(CDROMREADTOCENTRY)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003650 sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00003651 break;
nethercote73b526f2004-10-31 18:48:21 +00003652 case VKI_CDROMMULTISESSION: /* 0x5310 */
njn22cfccb2004-11-27 16:10:23 +00003653 PRE_MEM_WRITE( "ioctl(CDROMMULTISESSION)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003654 sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00003655 break;
nethercote73b526f2004-10-31 18:48:21 +00003656 case VKI_CDROMVOLREAD: /* 0x5313 */
njn22cfccb2004-11-27 16:10:23 +00003657 PRE_MEM_WRITE( "ioctl(CDROMVOLREAD)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003658 sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00003659 break;
tomf9d83852006-05-08 11:37:04 +00003660 case VKI_CDROMREADRAW: /* 0x5314 */
3661 PRE_MEM_READ( "ioctl(CDROMREADRAW)", ARG3, sizeof(struct vki_cdrom_msf));
3662 PRE_MEM_WRITE( "ioctl(CDROMREADRAW)", ARG3, VKI_CD_FRAMESIZE_RAW);
3663 break;
nethercote73b526f2004-10-31 18:48:21 +00003664 case VKI_CDROMREADAUDIO: /* 0x530e */
njn22cfccb2004-11-27 16:10:23 +00003665 PRE_MEM_READ( "ioctl(CDROMREADAUDIO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003666 sizeof (struct vki_cdrom_read_audio));
njn22cfccb2004-11-27 16:10:23 +00003667 if ( ARG3 ) {
thughes5b788fb2004-09-11 15:07:14 +00003668 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003669 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00003670 PRE_MEM_WRITE( "ioctl(CDROMREADAUDIO).buf",
3671 (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00003672 }
3673 break;
nethercote73b526f2004-10-31 18:48:21 +00003674 case VKI_CDROMPLAYMSF:
njn22cfccb2004-11-27 16:10:23 +00003675 PRE_MEM_READ( "ioctl(CDROMPLAYMSF)", ARG3, sizeof(struct vki_cdrom_msf));
jsgf855d93d2003-10-13 22:26:55 +00003676 break;
3677 /* The following two are probably bogus (should check args
3678 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00003679 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
3680 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00003681 break;
thughes66d80092004-06-19 12:41:05 +00003682
nethercote73b526f2004-10-31 18:48:21 +00003683 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00003684 PRE_MEM_WRITE( "ioctl(FIGETBSZ)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003685 break;
nethercote73b526f2004-10-31 18:48:21 +00003686 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00003687 PRE_MEM_READ( "ioctl(FIBMAP)", ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00003688 break;
3689
nethercote73b526f2004-10-31 18:48:21 +00003690 case VKI_FBIOGET_VSCREENINFO: /* 0x4600 */
njn22cfccb2004-11-27 16:10:23 +00003691 PRE_MEM_WRITE( "ioctl(FBIOGET_VSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003692 sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003693 break;
nethercote73b526f2004-10-31 18:48:21 +00003694 case VKI_FBIOGET_FSCREENINFO: /* 0x4602 */
njn22cfccb2004-11-27 16:10:23 +00003695 PRE_MEM_WRITE( "ioctl(FBIOGET_FSCREENINFO)", ARG3,
nethercote73b526f2004-10-31 18:48:21 +00003696 sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00003697 break;
jsgf855d93d2003-10-13 22:26:55 +00003698
nethercote73b526f2004-10-31 18:48:21 +00003699 case VKI_PPCLAIM:
3700 case VKI_PPEXCL:
3701 case VKI_PPYIELD:
3702 case VKI_PPRELEASE:
thughesd9895482004-08-16 19:46:55 +00003703 break;
nethercote73b526f2004-10-31 18:48:21 +00003704 case VKI_PPSETMODE:
njn22cfccb2004-11-27 16:10:23 +00003705 PRE_MEM_READ( "ioctl(PPSETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003706 break;
nethercote73b526f2004-10-31 18:48:21 +00003707 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003708 PRE_MEM_WRITE( "ioctl(PPGETMODE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003709 break;
nethercote73b526f2004-10-31 18:48:21 +00003710 case VKI_PPSETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003711 PRE_MEM_READ( "ioctl(PPSETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003712 break;
nethercote73b526f2004-10-31 18:48:21 +00003713 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00003714 PRE_MEM_WRITE( "ioctl(PPGETPHASE)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003715 break;
nethercote73b526f2004-10-31 18:48:21 +00003716 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00003717 PRE_MEM_WRITE( "ioctl(PPGETMODES)", ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00003718 break;
nethercote73b526f2004-10-31 18:48:21 +00003719 case VKI_PPSETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003720 PRE_MEM_READ( "ioctl(PPSETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003721 break;
nethercote73b526f2004-10-31 18:48:21 +00003722 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00003723 PRE_MEM_WRITE( "ioctl(PPGETFLAGS)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003724 break;
nethercote73b526f2004-10-31 18:48:21 +00003725 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00003726 PRE_MEM_WRITE( "ioctl(PPRSTATUS)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003727 break;
nethercote73b526f2004-10-31 18:48:21 +00003728 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00003729 PRE_MEM_WRITE( "ioctl(PPRDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003730 break;
nethercote73b526f2004-10-31 18:48:21 +00003731 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003732 PRE_MEM_WRITE( "ioctl(PPRCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003733 break;
nethercote73b526f2004-10-31 18:48:21 +00003734 case VKI_PPWDATA:
njn22cfccb2004-11-27 16:10:23 +00003735 PRE_MEM_READ( "ioctl(PPWDATA)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003736 break;
nethercote73b526f2004-10-31 18:48:21 +00003737 case VKI_PPWCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003738 PRE_MEM_READ( "ioctl(PPWCONTROL)", ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003739 break;
nethercote73b526f2004-10-31 18:48:21 +00003740 case VKI_PPFCONTROL:
njn22cfccb2004-11-27 16:10:23 +00003741 PRE_MEM_READ( "ioctl(PPFCONTROL)", ARG3, 2 * sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003742 break;
nethercote73b526f2004-10-31 18:48:21 +00003743 case VKI_PPDATADIR:
njn22cfccb2004-11-27 16:10:23 +00003744 PRE_MEM_READ( "ioctl(PPDATADIR)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003745 break;
nethercote73b526f2004-10-31 18:48:21 +00003746 case VKI_PPNEGOT:
njn22cfccb2004-11-27 16:10:23 +00003747 PRE_MEM_READ( "ioctl(PPNEGOT)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003748 break;
nethercote73b526f2004-10-31 18:48:21 +00003749 case VKI_PPWCTLONIRQ:
njn22cfccb2004-11-27 16:10:23 +00003750 PRE_MEM_READ( "ioctl(PPWCTLONIRQ)",ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00003751 break;
nethercote73b526f2004-10-31 18:48:21 +00003752 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00003753 PRE_MEM_WRITE( "ioctl(PPCLRIRQ)", ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00003754 break;
nethercote73b526f2004-10-31 18:48:21 +00003755 case VKI_PPSETTIME:
njn22cfccb2004-11-27 16:10:23 +00003756 PRE_MEM_READ( "ioctl(PPSETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003757 break;
nethercote73b526f2004-10-31 18:48:21 +00003758 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00003759 PRE_MEM_WRITE( "ioctl(PPGETTIME)", ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00003760 break;
3761
thughesb3d3bcf2004-11-13 00:36:15 +00003762 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003763 PRE_MEM_WRITE( "ioctl(GIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003764 break;
3765 case VKI_PIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00003766 PRE_MEM_READ( "ioctl(PIO_FONT)", ARG3, 32 * 256 );
thughesb3d3bcf2004-11-13 00:36:15 +00003767 break;
3768
3769 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003770 PRE_MEM_READ( "ioctl(GIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3771 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003772 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003773 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003774 PRE_MEM_WRITE( "ioctl(GIO_FONTX).chardata", (Addr)cfd->chardata,
3775 32 * cfd->charcount );
3776 }
3777 break;
3778 case VKI_PIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00003779 PRE_MEM_READ( "ioctl(PIO_FONTX)", ARG3, sizeof(struct vki_consolefontdesc) );
3780 if ( ARG3 ) {
thughesb3d3bcf2004-11-13 00:36:15 +00003781 /* ToDo: don't do any of the following if the structure is invalid */
njn22cfccb2004-11-27 16:10:23 +00003782 struct vki_consolefontdesc *cfd = (struct vki_consolefontdesc *)ARG3;
thughesb3d3bcf2004-11-13 00:36:15 +00003783 PRE_MEM_READ( "ioctl(PIO_FONTX).chardata", (Addr)cfd->chardata,
3784 32 * cfd->charcount );
3785 }
3786 break;
3787
3788 case VKI_PIO_FONTRESET:
3789 break;
3790
3791 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003792 PRE_MEM_WRITE( "ioctl(GIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003793 break;
3794 case VKI_PIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00003795 PRE_MEM_READ( "ioctl(PIO_CMAP)", ARG3, 16 * 3 );
thughesb3d3bcf2004-11-13 00:36:15 +00003796 break;
3797
3798 case VKI_KIOCSOUND:
3799 case VKI_KDMKTONE:
3800 break;
3801
3802 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00003803 PRE_MEM_WRITE( "ioctl(KDGETLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003804 break;
3805 case VKI_KDSETLED:
3806 break;
3807
3808 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00003809 PRE_MEM_WRITE( "ioctl(KDGKBTYPE)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003810 break;
3811
3812 case VKI_KDADDIO:
3813 case VKI_KDDELIO:
3814 case VKI_KDENABIO:
3815 case VKI_KDDISABIO:
3816 break;
3817
3818 case VKI_KDSETMODE:
3819 break;
3820 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00003821 PRE_MEM_WRITE( "ioctl(KDGETMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003822 break;
3823
3824 case VKI_KDMAPDISP:
3825 case VKI_KDUNMAPDISP:
3826 break;
3827
3828 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003829 PRE_MEM_WRITE( "ioctl(GIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003830 break;
3831 case VKI_PIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003832 PRE_MEM_READ( "ioctl(PIO_SCRNMAP)", ARG3, VKI_E_TABSZ );
thughesb3d3bcf2004-11-13 00:36:15 +00003833 break;
3834 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003835 PRE_MEM_WRITE( "ioctl(GIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003836 VKI_E_TABSZ * sizeof(unsigned short) );
3837 break;
3838 case VKI_PIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00003839 PRE_MEM_READ( "ioctl(PIO_UNISCRNMAP)", ARG3,
thughesb3d3bcf2004-11-13 00:36:15 +00003840 VKI_E_TABSZ * sizeof(unsigned short) );
3841 break;
3842
tom053eb042006-06-07 18:35:34 +00003843 case VKI_GIO_UNIMAP:
3844 if ( ARG3 ) {
3845 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
3846 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
3847 sizeof(unsigned short));
3848 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
3849 sizeof(struct vki_unipair *));
3850 PRE_MEM_WRITE( "ioctl(GIO_UNIMAP).entries", (Addr)desc->entries,
3851 desc->entry_ct * sizeof(struct vki_unipair));
3852 }
3853 break;
3854 case VKI_PIO_UNIMAP:
3855 if ( ARG3 ) {
3856 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
3857 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entry_ct,
3858 sizeof(unsigned short) );
3859 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", (Addr)&desc->entries,
3860 sizeof(struct vki_unipair *) );
3861 PRE_MEM_READ( "ioctl(PIO_UNIMAP).entries", (Addr)desc->entries,
3862 desc->entry_ct * sizeof(struct vki_unipair) );
3863 }
3864 break;
3865 case VKI_PIO_UNIMAPCLR:
3866 PRE_MEM_READ( "ioctl(GIO_UNIMAP)", ARG3, sizeof(struct vki_unimapinit));
3867 break;
3868
thughesb3d3bcf2004-11-13 00:36:15 +00003869 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00003870 PRE_MEM_WRITE( "ioctl(KDGKBMODE)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003871 break;
3872 case VKI_KDSKBMODE:
3873 break;
3874
3875 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00003876 PRE_MEM_WRITE( "ioctl(KDGKBMETA)", ARG3, sizeof(int) );
thughesb3d3bcf2004-11-13 00:36:15 +00003877 break;
3878 case VKI_KDSKBMETA:
3879 break;
3880
3881 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00003882 PRE_MEM_WRITE( "ioctl(KDGKBLED)", ARG3, sizeof(char) );
thughesb3d3bcf2004-11-13 00:36:15 +00003883 break;
3884 case VKI_KDSKBLED:
3885 break;
3886
3887 case VKI_KDGKBENT:
3888 PRE_MEM_READ( "ioctl(KDGKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003889 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3890 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003891 PRE_MEM_READ( "ioctl(KDGKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003892 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3893 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003894 PRE_MEM_WRITE( "ioctl(KDGKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003895 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3896 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003897 break;
3898 case VKI_KDSKBENT:
3899 PRE_MEM_READ( "ioctl(KDSKBENT).kb_table",
njn22cfccb2004-11-27 16:10:23 +00003900 (Addr)&((struct vki_kbentry *)ARG3)->kb_table,
3901 sizeof(((struct vki_kbentry *)ARG3)->kb_table) );
thughesb3d3bcf2004-11-13 00:36:15 +00003902 PRE_MEM_READ( "ioctl(KDSKBENT).kb_index",
njn22cfccb2004-11-27 16:10:23 +00003903 (Addr)&((struct vki_kbentry *)ARG3)->kb_index,
3904 sizeof(((struct vki_kbentry *)ARG3)->kb_index) );
thughesb3d3bcf2004-11-13 00:36:15 +00003905 PRE_MEM_READ( "ioctl(KDSKBENT).kb_value",
njn22cfccb2004-11-27 16:10:23 +00003906 (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
3907 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesb3d3bcf2004-11-13 00:36:15 +00003908 break;
3909
3910 case VKI_KDGKBSENT:
3911 PRE_MEM_READ( "ioctl(KDGKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003912 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3913 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003914 PRE_MEM_WRITE( "ioctl(KDGKSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003915 (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
3916 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesb3d3bcf2004-11-13 00:36:15 +00003917 break;
3918 case VKI_KDSKBSENT:
3919 PRE_MEM_READ( "ioctl(KDSKBSENT).kb_func",
njn22cfccb2004-11-27 16:10:23 +00003920 (Addr)&((struct vki_kbsentry *)ARG3)->kb_func,
3921 sizeof(((struct vki_kbsentry *)ARG3)->kb_func) );
thughesb3d3bcf2004-11-13 00:36:15 +00003922 PRE_MEM_RASCIIZ( "ioctl(KDSKBSENT).kb_string",
njn22cfccb2004-11-27 16:10:23 +00003923 (Addr)((struct vki_kbsentry *)ARG3)->kb_string );
thughesb3d3bcf2004-11-13 00:36:15 +00003924 break;
3925
3926 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003927 PRE_MEM_WRITE( "ioctl(KDGKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003928 break;
3929 case VKI_KDSKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00003930 PRE_MEM_READ( "ioctl(KDSKBDIACR)", ARG3, sizeof(struct vki_kbdiacrs) );
thughesb3d3bcf2004-11-13 00:36:15 +00003931 break;
3932
3933 case VKI_KDGETKEYCODE:
3934 PRE_MEM_READ( "ioctl(KDGETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003935 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3936 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003937 PRE_MEM_WRITE( "ioctl(KDGETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003938 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3939 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003940 break;
3941 case VKI_KDSETKEYCODE:
3942 PRE_MEM_READ( "ioctl(KDSETKEYCODE).scancode",
njn22cfccb2004-11-27 16:10:23 +00003943 (Addr)&((struct vki_kbkeycode *)ARG3)->scancode,
3944 sizeof(((struct vki_kbkeycode *)ARG3)->scancode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003945 PRE_MEM_READ( "ioctl(KDSETKEYCODE).keycode",
njn22cfccb2004-11-27 16:10:23 +00003946 (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
3947 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesb3d3bcf2004-11-13 00:36:15 +00003948 break;
3949
3950 case VKI_KDSIGACCEPT:
3951 break;
3952
3953 case VKI_KDKBDREP:
njn22cfccb2004-11-27 16:10:23 +00003954 PRE_MEM_READ( "ioctl(KBKBDREP)", ARG3, sizeof(struct vki_kbd_repeat) );
thughesb3d3bcf2004-11-13 00:36:15 +00003955 break;
tom053eb042006-06-07 18:35:34 +00003956
3957 case VKI_KDFONTOP:
3958 if ( ARG3 ) {
3959 struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
3960 PRE_MEM_READ( "ioctl(KDFONTOP)", (Addr)op,
3961 sizeof(struct vki_console_font_op) );
3962 switch ( op->op ) {
3963 case VKI_KD_FONT_OP_SET:
3964 PRE_MEM_READ( "ioctl(KDFONTOP,KD_FONT_OP_SET).data",
3965 (Addr)op->data,
3966 (op->width + 7) / 8 * 32 * op->charcount );
3967 break;
3968 case VKI_KD_FONT_OP_GET:
3969 if ( op->data )
3970 PRE_MEM_WRITE( "ioctl(KDFONTOP,KD_FONT_OP_GET).data",
3971 (Addr)op->data,
3972 (op->width + 7) / 8 * 32 * op->charcount );
3973 break;
3974 case VKI_KD_FONT_OP_SET_DEFAULT:
3975 if ( op->data )
3976 PRE_MEM_RASCIIZ( "ioctl(KDFONTOP,KD_FONT_OP_SET_DEFAULT).data",
3977 (Addr)op->data );
3978 break;
3979 case VKI_KD_FONT_OP_COPY:
3980 break;
3981 }
3982 }
3983 break;
3984
3985 case VKI_VT_OPENQRY:
3986 PRE_MEM_WRITE( "ioctl(VT_OPENQRY)", ARG3, sizeof(int) );
3987 break;
3988 case VKI_VT_GETMODE:
3989 PRE_MEM_WRITE( "ioctl(VT_GETMODE)", ARG3, sizeof(struct vki_vt_mode) );
3990 break;
3991 case VKI_VT_SETMODE:
3992 PRE_MEM_READ( "ioctl(VT_SETMODE)", ARG3, sizeof(struct vki_vt_mode) );
3993 break;
3994 case VKI_VT_GETSTATE:
3995 PRE_MEM_READ( "ioctl(VT_GETSTATE)", ARG3, sizeof(struct vki_vt_stat) );
3996 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_active",
3997 (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
3998 sizeof(((struct vki_vt_stat*) ARG3)->v_active));
3999 PRE_MEM_WRITE( "ioctl(VT_GETSTATE).v_state",
4000 (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
4001 sizeof(((struct vki_vt_stat*) ARG3)->v_state));
4002 break;
4003 case VKI_VT_RELDISP:
4004 case VKI_VT_ACTIVATE:
4005 case VKI_VT_WAITACTIVE:
4006 case VKI_VT_DISALLOCATE:
4007 break;
4008 case VKI_VT_RESIZE:
4009 PRE_MEM_READ( "ioctl(VT_RESIZE)", ARG3, sizeof(struct vki_vt_sizes) );
4010 break;
4011 case VKI_VT_RESIZEX:
4012 PRE_MEM_READ( "ioctl(VT_RESIZEX)", ARG3, sizeof(struct vki_vt_consize) );
4013 break;
4014 case VKI_VT_LOCKSWITCH:
4015 case VKI_VT_UNLOCKSWITCH:
4016 break;
4017
thughesb3d3bcf2004-11-13 00:36:15 +00004018
jsgf855d93d2003-10-13 22:26:55 +00004019 /* We don't have any specific information on it, so
4020 try to do something reasonable based on direction and
4021 size bits. The encoding scheme is described in
4022 /usr/include/asm/ioctl.h.
4023
4024 According to Simon Hausmann, _IOC_READ means the kernel
4025 writes a value to the ioctl value passed from the user
4026 space and the other way around with _IOC_WRITE. */
4027 default: {
njn22cfccb2004-11-27 16:10:23 +00004028 UInt dir = _VKI_IOC_DIR(ARG2);
4029 UInt size = _VKI_IOC_SIZE(ARG2);
njn628add62005-11-12 18:21:40 +00004030 if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) {
jsgf855d93d2003-10-13 22:26:55 +00004031 /*
4032 * Be very lax about ioctl handling; the only
4033 * assumption is that the size is correct. Doesn't
4034 * require the full buffer to be initialized when
4035 * writing. Without this, using some device
4036 * drivers with a large number of strange ioctl
4037 * commands becomes very tiresome.
4038 */
nethercote73b526f2004-10-31 18:48:21 +00004039 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
jsgf855d93d2003-10-13 22:26:55 +00004040 static Int moans = 3;
sewardj1fa7d2c2005-06-13 18:22:17 +00004041 if (moans > 0 && !VG_(clo_xml)) {
jsgf855d93d2003-10-13 22:26:55 +00004042 moans--;
4043 VG_(message)(Vg_UserMsg,
4044 "Warning: noted but unhandled ioctl 0x%x"
4045 " with no size/direction hints",
njn22cfccb2004-11-27 16:10:23 +00004046 ARG2);
jsgf855d93d2003-10-13 22:26:55 +00004047 VG_(message)(Vg_UserMsg,
4048 " This could cause spurious value errors"
4049 " to appear.");
4050 VG_(message)(Vg_UserMsg,
4051 " See README_MISSING_SYSCALL_OR_IOCTL for "
4052 "guidance on writing a proper wrapper." );
4053 }
4054 } else {
nethercote73b526f2004-10-31 18:48:21 +00004055 if ((dir & _VKI_IOC_WRITE) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00004056 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
nethercote73b526f2004-10-31 18:48:21 +00004057 if ((dir & _VKI_IOC_READ) && size > 0)
njn22cfccb2004-11-27 16:10:23 +00004058 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00004059 }
4060 break;
4061 }
4062 }
4063}
4064
nethercote85a456f2004-11-16 17:31:56 +00004065POST(sys_ioctl)
jsgf855d93d2003-10-13 22:26:55 +00004066{
sewardja8d8e232005-06-07 20:04:56 +00004067 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00004068 switch (ARG2 /* request */) {
nethercote73b526f2004-10-31 18:48:21 +00004069 case VKI_TCSETS:
4070 case VKI_TCSETSW:
4071 case VKI_TCSETSF:
jsgf855d93d2003-10-13 22:26:55 +00004072 break;
nethercote73b526f2004-10-31 18:48:21 +00004073 case VKI_TCGETS:
njn22cfccb2004-11-27 16:10:23 +00004074 POST_MEM_WRITE( ARG3, sizeof(struct vki_termios) );
jsgf855d93d2003-10-13 22:26:55 +00004075 break;
nethercote73b526f2004-10-31 18:48:21 +00004076 case VKI_TCSETA:
4077 case VKI_TCSETAW:
4078 case VKI_TCSETAF:
jsgf855d93d2003-10-13 22:26:55 +00004079 break;
nethercote73b526f2004-10-31 18:48:21 +00004080 case VKI_TCGETA:
njn22cfccb2004-11-27 16:10:23 +00004081 POST_MEM_WRITE( ARG3, sizeof(struct vki_termio) );
jsgf855d93d2003-10-13 22:26:55 +00004082 break;
nethercote73b526f2004-10-31 18:48:21 +00004083 case VKI_TCSBRK:
4084 case VKI_TCXONC:
4085 case VKI_TCSBRKP:
4086 case VKI_TCFLSH:
jsgf855d93d2003-10-13 22:26:55 +00004087 break;
nethercote73b526f2004-10-31 18:48:21 +00004088 case VKI_TIOCGWINSZ:
njn22cfccb2004-11-27 16:10:23 +00004089 POST_MEM_WRITE( ARG3, sizeof(struct vki_winsize) );
jsgf855d93d2003-10-13 22:26:55 +00004090 break;
nethercote73b526f2004-10-31 18:48:21 +00004091 case VKI_TIOCSWINSZ:
4092 case VKI_TIOCMBIS:
4093 case VKI_TIOCMBIC:
4094 case VKI_TIOCMSET:
jsgf855d93d2003-10-13 22:26:55 +00004095 break;
tom62ba7582005-07-28 16:26:34 +00004096 case VKI_TIOCMGET:
4097 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
4098 break;
nethercote73b526f2004-10-31 18:48:21 +00004099 case VKI_TIOCLINUX:
njn22cfccb2004-11-27 16:10:23 +00004100 POST_MEM_WRITE( ARG3, sizeof(char *) );
jsgf855d93d2003-10-13 22:26:55 +00004101 break;
nethercote73b526f2004-10-31 18:48:21 +00004102 case VKI_TIOCGPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004103 /* Get process group ID for foreground processing group. */
njn22cfccb2004-11-27 16:10:23 +00004104 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004105 break;
nethercote73b526f2004-10-31 18:48:21 +00004106 case VKI_TIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004107 /* Set a process group ID? */
njn22cfccb2004-11-27 16:10:23 +00004108 POST_MEM_WRITE( ARG3, sizeof(vki_pid_t) );
jsgf855d93d2003-10-13 22:26:55 +00004109 break;
nethercote73b526f2004-10-31 18:48:21 +00004110 case VKI_TIOCGPTN: /* Get Pty Number (of pty-mux device) */
njn22cfccb2004-11-27 16:10:23 +00004111 POST_MEM_WRITE( ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004112 break;
nethercote73b526f2004-10-31 18:48:21 +00004113 case VKI_TIOCSCTTY:
jsgf855d93d2003-10-13 22:26:55 +00004114 break;
nethercote73b526f2004-10-31 18:48:21 +00004115 case VKI_TIOCSPTLCK: /* Lock/unlock Pty */
jsgf855d93d2003-10-13 22:26:55 +00004116 break;
nethercote73b526f2004-10-31 18:48:21 +00004117 case VKI_FIONBIO:
jsgf855d93d2003-10-13 22:26:55 +00004118 break;
nethercote73b526f2004-10-31 18:48:21 +00004119 case VKI_FIOASYNC:
jsgf855d93d2003-10-13 22:26:55 +00004120 break;
nethercote73b526f2004-10-31 18:48:21 +00004121 case VKI_FIONREAD: /* identical to SIOCINQ */
njn22cfccb2004-11-27 16:10:23 +00004122 POST_MEM_WRITE( ARG3, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00004123 break;
4124
tom5d2af672006-02-11 13:29:09 +00004125 case VKI_TIOCSERGETLSR:
4126 POST_MEM_WRITE( ARG3, sizeof(int) );
4127 break;
4128 case VKI_TIOCGICOUNT:
4129 POST_MEM_WRITE( ARG3, sizeof(struct vki_serial_icounter_struct) );
4130 break;
4131
nethercote73b526f2004-10-31 18:48:21 +00004132 case VKI_SG_SET_COMMAND_Q:
jsgf855d93d2003-10-13 22:26:55 +00004133 break;
nethercote73b526f2004-10-31 18:48:21 +00004134 case VKI_SG_IO:
njn22cfccb2004-11-27 16:10:23 +00004135 POST_MEM_WRITE(ARG3, sizeof(vki_sg_io_hdr_t));
jsgf855d93d2003-10-13 22:26:55 +00004136 break;
nethercote73b526f2004-10-31 18:48:21 +00004137 case VKI_SG_GET_SCSI_ID:
njn22cfccb2004-11-27 16:10:23 +00004138 POST_MEM_WRITE(ARG3, sizeof(vki_sg_scsi_id_t));
jsgf855d93d2003-10-13 22:26:55 +00004139 break;
nethercote73b526f2004-10-31 18:48:21 +00004140 case VKI_SG_SET_RESERVED_SIZE:
jsgf855d93d2003-10-13 22:26:55 +00004141 break;
nethercote73b526f2004-10-31 18:48:21 +00004142 case VKI_SG_SET_TIMEOUT:
jsgf855d93d2003-10-13 22:26:55 +00004143 break;
nethercote73b526f2004-10-31 18:48:21 +00004144 case VKI_SG_GET_RESERVED_SIZE:
njn22cfccb2004-11-27 16:10:23 +00004145 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004146 break;
nethercote73b526f2004-10-31 18:48:21 +00004147 case VKI_SG_GET_TIMEOUT:
njn22cfccb2004-11-27 16:10:23 +00004148 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004149 break;
nethercote73b526f2004-10-31 18:48:21 +00004150 case VKI_SG_GET_VERSION_NUM:
jsgf855d93d2003-10-13 22:26:55 +00004151 break;
nethercote73b526f2004-10-31 18:48:21 +00004152 case VKI_SG_EMULATED_HOST:
njn22cfccb2004-11-27 16:10:23 +00004153 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00004154 break;
nethercote73b526f2004-10-31 18:48:21 +00004155 case VKI_SG_GET_SG_TABLESIZE:
njn22cfccb2004-11-27 16:10:23 +00004156 POST_MEM_WRITE(ARG3, sizeof(int));
thughes5b788fb2004-09-11 15:07:14 +00004157 break;
jsgf855d93d2003-10-13 22:26:55 +00004158
muellera4b153a2003-11-19 22:07:14 +00004159 case VKI_IIOCGETCPS:
njn22cfccb2004-11-27 16:10:23 +00004160 POST_MEM_WRITE( ARG3, VKI_ISDN_MAX_CHANNELS * 2 * sizeof(unsigned long) );
jsgf855d93d2003-10-13 22:26:55 +00004161 break;
muellera4b153a2003-11-19 22:07:14 +00004162 case VKI_IIOCNETGPN:
njn22cfccb2004-11-27 16:10:23 +00004163 POST_MEM_WRITE( ARG3, sizeof(vki_isdn_net_ioctl_phone) );
jsgf855d93d2003-10-13 22:26:55 +00004164 break;
4165
4166 /* These all use struct ifreq AFAIK */
nethercote73b526f2004-10-31 18:48:21 +00004167 case VKI_SIOCGIFINDEX: /* get iface index */
njn22cfccb2004-11-27 16:10:23 +00004168 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_ifindex,
4169 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_ifindex) );
thughesbe811712004-06-17 23:04:58 +00004170 break;
nethercote73b526f2004-10-31 18:48:21 +00004171 case VKI_SIOCGIFFLAGS: /* get flags */
njn22cfccb2004-11-27 16:10:23 +00004172 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_flags,
4173 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_flags) );
thughesbe811712004-06-17 23:04:58 +00004174 break;
nethercote73b526f2004-10-31 18:48:21 +00004175 case VKI_SIOCGIFHWADDR: /* Get hardware address */
njn22cfccb2004-11-27 16:10:23 +00004176 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->ifr_hwaddr,
4177 sizeof(((struct vki_ifreq *)ARG3)->ifr_hwaddr) );
thughesbe811712004-06-17 23:04:58 +00004178 break;
nethercote73b526f2004-10-31 18:48:21 +00004179 case VKI_SIOCGIFMTU: /* get MTU size */
njn22cfccb2004-11-27 16:10:23 +00004180 POST_MEM_WRITE( (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_mtu,
4181 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_mtu) );
thughesbe811712004-06-17 23:04:58 +00004182 break;
nethercote73b526f2004-10-31 18:48:21 +00004183 case VKI_SIOCGIFADDR: /* get PA address */
4184 case VKI_SIOCGIFDSTADDR: /* get remote PA address */
4185 case VKI_SIOCGIFBRDADDR: /* get broadcast PA address */
4186 case VKI_SIOCGIFNETMASK: /* get network PA mask */
njncf45fd42004-11-24 16:30:22 +00004187 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004188 (Addr)&((struct vki_ifreq *)ARG3)->ifr_addr,
4189 sizeof(((struct vki_ifreq *)ARG3)->ifr_addr) );
thughesbe811712004-06-17 23:04:58 +00004190 break;
nethercote73b526f2004-10-31 18:48:21 +00004191 case VKI_SIOCGIFMETRIC: /* get metric */
njncf45fd42004-11-24 16:30:22 +00004192 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004193 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_metric,
4194 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_metric) );
thughesbe811712004-06-17 23:04:58 +00004195 break;
nethercote73b526f2004-10-31 18:48:21 +00004196 case VKI_SIOCGIFMAP: /* Get device parameters */
njncf45fd42004-11-24 16:30:22 +00004197 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004198 (Addr)&((struct vki_ifreq *)ARG3)->ifr_map,
4199 sizeof(((struct vki_ifreq *)ARG3)->ifr_map) );
thughesbe811712004-06-17 23:04:58 +00004200 break;
4201 break;
nethercote73b526f2004-10-31 18:48:21 +00004202 case VKI_SIOCGIFTXQLEN: /* Get the tx queue length */
njncf45fd42004-11-24 16:30:22 +00004203 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004204 (Addr)&((struct vki_ifreq *)ARG3)->ifr_qlen,
4205 sizeof(((struct vki_ifreq *)ARG3)->ifr_qlen) );
thughesbe811712004-06-17 23:04:58 +00004206 break;
nethercote73b526f2004-10-31 18:48:21 +00004207 case VKI_SIOCGIFNAME: /* get iface name */
njncf45fd42004-11-24 16:30:22 +00004208 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004209 (Addr)&((struct vki_ifreq *)ARG3)->vki_ifr_name,
4210 sizeof(((struct vki_ifreq *)ARG3)->vki_ifr_name) );
jsgf855d93d2003-10-13 22:26:55 +00004211 break;
nethercote73b526f2004-10-31 18:48:21 +00004212 case VKI_SIOCGMIIPHY: /* get hardware entry */
njncf45fd42004-11-24 16:30:22 +00004213 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004214 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id,
4215 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->phy_id) );
thughesbe811712004-06-17 23:04:58 +00004216 break;
nethercote73b526f2004-10-31 18:48:21 +00004217 case VKI_SIOCGMIIREG: /* get hardware entry registers */
njncf45fd42004-11-24 16:30:22 +00004218 POST_MEM_WRITE(
njn22cfccb2004-11-27 16:10:23 +00004219 (Addr)&((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out,
4220 sizeof(((struct vki_mii_ioctl_data *)&((struct vki_ifreq *)ARG3)->vki_ifr_data)->val_out) );
thughesbe811712004-06-17 23:04:58 +00004221 break;
nethercote73b526f2004-10-31 18:48:21 +00004222 case VKI_SIOCGIFCONF: /* get iface list */
jsgf855d93d2003-10-13 22:26:55 +00004223 /* WAS:
njn22cfccb2004-11-27 16:10:23 +00004224 PRE_MEM_WRITE("ioctl(SIOCGIFCONF)", ARG3, sizeof(struct ifconf));
4225 KERNEL_DO_SYSCALL(tid,RES);
4226 if (!VG_(is_kerror)(RES) && RES == 0)
4227 POST_MEM_WRITE(ARG3, sizeof(struct ifconf));
jsgf855d93d2003-10-13 22:26:55 +00004228 */
njn22cfccb2004-11-27 16:10:23 +00004229 if (RES == 0 && ARG3 ) {
4230 struct vki_ifconf *ifc = (struct vki_ifconf *) ARG3;
nethercote73b526f2004-10-31 18:48:21 +00004231 if (ifc->vki_ifc_buf != NULL)
nethercoteef0c7662004-11-06 15:38:43 +00004232 POST_MEM_WRITE( (Addr)(ifc->vki_ifc_buf), ifc->ifc_len );
jsgf855d93d2003-10-13 22:26:55 +00004233 }
4234 break;
nethercote73b526f2004-10-31 18:48:21 +00004235 case VKI_SIOCGSTAMP:
njn22cfccb2004-11-27 16:10:23 +00004236 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
jsgf855d93d2003-10-13 22:26:55 +00004237 break;
4238 /* SIOCOUTQ is an ioctl that, when called on a socket, returns
4239 the number of bytes currently in that socket's send buffer.
4240 It writes this value as an int to the memory location
4241 indicated by the third argument of ioctl(2). */
nethercote73b526f2004-10-31 18:48:21 +00004242 case VKI_SIOCOUTQ:
njn22cfccb2004-11-27 16:10:23 +00004243 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004244 break;
nethercote73b526f2004-10-31 18:48:21 +00004245 case VKI_SIOCGRARP: /* get RARP table entry */
4246 case VKI_SIOCGARP: /* get ARP table entry */
njn22cfccb2004-11-27 16:10:23 +00004247 POST_MEM_WRITE(ARG3, sizeof(struct vki_arpreq));
jsgf855d93d2003-10-13 22:26:55 +00004248 break;
4249
nethercote73b526f2004-10-31 18:48:21 +00004250 case VKI_SIOCSIFFLAGS: /* set flags */
4251 case VKI_SIOCSIFMAP: /* Set device parameters */
4252 case VKI_SIOCSIFTXQLEN: /* Set the tx queue length */
4253 case VKI_SIOCSIFDSTADDR: /* set remote PA address */
4254 case VKI_SIOCSIFBRDADDR: /* set broadcast PA address */
4255 case VKI_SIOCSIFNETMASK: /* set network PA mask */
4256 case VKI_SIOCSIFMETRIC: /* set metric */
4257 case VKI_SIOCSIFADDR: /* set PA address */
4258 case VKI_SIOCSIFMTU: /* set MTU size */
4259 case VKI_SIOCSIFHWADDR: /* set hardware address */
4260 case VKI_SIOCSMIIREG: /* set hardware entry registers */
jsgf855d93d2003-10-13 22:26:55 +00004261 break;
4262 /* Routing table calls. */
nethercote73b526f2004-10-31 18:48:21 +00004263 case VKI_SIOCADDRT: /* add routing table entry */
4264 case VKI_SIOCDELRT: /* delete routing table entry */
jsgf855d93d2003-10-13 22:26:55 +00004265 break;
4266
4267 /* RARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004268 case VKI_SIOCDRARP: /* delete RARP table entry */
4269 case VKI_SIOCSRARP: /* set RARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004270 /* ARP cache control calls. */
nethercote73b526f2004-10-31 18:48:21 +00004271 case VKI_SIOCSARP: /* set ARP table entry */
4272 case VKI_SIOCDARP: /* delete ARP table entry */
jsgf855d93d2003-10-13 22:26:55 +00004273 break;
4274
nethercote73b526f2004-10-31 18:48:21 +00004275 case VKI_SIOCGPGRP:
njn22cfccb2004-11-27 16:10:23 +00004276 POST_MEM_WRITE(ARG3, sizeof(int));
thughes1174fed2004-09-11 15:33:17 +00004277 break;
nethercote73b526f2004-10-31 18:48:21 +00004278 case VKI_SIOCSPGRP:
jsgf855d93d2003-10-13 22:26:55 +00004279 break;
4280
4281 /* linux/soundcard interface (OSS) */
nethercote73b526f2004-10-31 18:48:21 +00004282 case VKI_SNDCTL_SEQ_GETOUTCOUNT:
4283 case VKI_SNDCTL_SEQ_GETINCOUNT:
4284 case VKI_SNDCTL_SEQ_PERCMODE:
4285 case VKI_SNDCTL_SEQ_TESTMIDI:
4286 case VKI_SNDCTL_SEQ_RESETSAMPLES:
4287 case VKI_SNDCTL_SEQ_NRSYNTHS:
4288 case VKI_SNDCTL_SEQ_NRMIDIS:
4289 case VKI_SNDCTL_SEQ_GETTIME:
4290 case VKI_SNDCTL_DSP_GETFMTS:
4291 case VKI_SNDCTL_DSP_GETTRIGGER:
4292 case VKI_SNDCTL_DSP_GETODELAY:
4293 case VKI_SNDCTL_DSP_GETSPDIF:
4294 case VKI_SNDCTL_DSP_GETCAPS:
4295 case VKI_SOUND_PCM_READ_RATE:
4296 case VKI_SOUND_PCM_READ_CHANNELS:
4297 case VKI_SOUND_PCM_READ_BITS:
sewardj2c48c7b2005-11-29 13:05:56 +00004298#if !defined(VGA_ppc32) && !defined(VGA_ppc64)
nethercote73b526f2004-10-31 18:48:21 +00004299 case (VKI_SOUND_PCM_READ_BITS|0x40000000): /* what the fuck ? */
cerion85665ca2005-06-20 15:51:07 +00004300#endif
nethercote73b526f2004-10-31 18:48:21 +00004301 case VKI_SOUND_PCM_READ_FILTER:
njn22cfccb2004-11-27 16:10:23 +00004302 POST_MEM_WRITE(ARG3, sizeof(int));
jsgf855d93d2003-10-13 22:26:55 +00004303 break;
nethercote73b526f2004-10-31 18:48:21 +00004304 case VKI_SNDCTL_SEQ_CTRLRATE:
4305 case VKI_SNDCTL_DSP_SPEED:
4306 case VKI_SNDCTL_DSP_STEREO:
4307 case VKI_SNDCTL_DSP_GETBLKSIZE:
4308 case VKI_SNDCTL_DSP_CHANNELS:
4309 case VKI_SOUND_PCM_WRITE_FILTER:
4310 case VKI_SNDCTL_DSP_SUBDIVIDE:
4311 case VKI_SNDCTL_DSP_SETFRAGMENT:
nethercote73b526f2004-10-31 18:48:21 +00004312 case VKI_SNDCTL_DSP_GETCHANNELMASK:
nethercote73b526f2004-10-31 18:48:21 +00004313 case VKI_SNDCTL_DSP_BIND_CHANNEL:
nethercote73b526f2004-10-31 18:48:21 +00004314 case VKI_SNDCTL_TMR_TIMEBASE:
4315 case VKI_SNDCTL_TMR_TEMPO:
4316 case VKI_SNDCTL_TMR_SOURCE:
4317 case VKI_SNDCTL_MIDI_PRETIME:
4318 case VKI_SNDCTL_MIDI_MPUMODE:
jsgf855d93d2003-10-13 22:26:55 +00004319 break;
nethercote73b526f2004-10-31 18:48:21 +00004320 case VKI_SNDCTL_DSP_GETOSPACE:
4321 case VKI_SNDCTL_DSP_GETISPACE:
njn22cfccb2004-11-27 16:10:23 +00004322 POST_MEM_WRITE(ARG3, sizeof(vki_audio_buf_info));
jsgf855d93d2003-10-13 22:26:55 +00004323 break;
nethercote73b526f2004-10-31 18:48:21 +00004324 case VKI_SNDCTL_DSP_SETTRIGGER:
jsgf855d93d2003-10-13 22:26:55 +00004325 break;
4326
nethercote73b526f2004-10-31 18:48:21 +00004327 case VKI_SNDCTL_DSP_POST:
4328 case VKI_SNDCTL_DSP_RESET:
4329 case VKI_SNDCTL_DSP_SYNC:
4330 case VKI_SNDCTL_DSP_SETSYNCRO:
4331 case VKI_SNDCTL_DSP_SETDUPLEX:
jsgf855d93d2003-10-13 22:26:55 +00004332 break;
4333
tom2f932882005-11-14 17:03:54 +00004334 /* linux/soundcard interface (ALSA) */
4335 case VKI_SNDRV_PCM_IOCTL_HW_FREE:
4336 case VKI_SNDRV_PCM_IOCTL_HWSYNC:
4337 case VKI_SNDRV_PCM_IOCTL_PREPARE:
4338 case VKI_SNDRV_PCM_IOCTL_RESET:
4339 case VKI_SNDRV_PCM_IOCTL_START:
4340 case VKI_SNDRV_PCM_IOCTL_DROP:
4341 case VKI_SNDRV_PCM_IOCTL_DRAIN:
4342 case VKI_SNDRV_PCM_IOCTL_RESUME:
4343 case VKI_SNDRV_PCM_IOCTL_XRUN:
4344 case VKI_SNDRV_PCM_IOCTL_UNLINK:
4345 case VKI_SNDRV_TIMER_IOCTL_START:
4346 case VKI_SNDRV_TIMER_IOCTL_STOP:
4347 case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
4348 case VKI_SNDRV_TIMER_IOCTL_PAUSE:
4349 break;
4350
jsgf855d93d2003-10-13 22:26:55 +00004351 /* Real Time Clock (/dev/rtc) ioctls */
nethercote73b526f2004-10-31 18:48:21 +00004352 case VKI_RTC_UIE_ON:
4353 case VKI_RTC_UIE_OFF:
4354 case VKI_RTC_AIE_ON:
4355 case VKI_RTC_AIE_OFF:
4356 case VKI_RTC_PIE_ON:
4357 case VKI_RTC_PIE_OFF:
4358 case VKI_RTC_IRQP_SET:
jsgf855d93d2003-10-13 22:26:55 +00004359 break;
nethercote73b526f2004-10-31 18:48:21 +00004360 case VKI_RTC_RD_TIME:
4361 case VKI_RTC_ALM_READ:
njn22cfccb2004-11-27 16:10:23 +00004362 POST_MEM_WRITE(ARG3, sizeof(struct vki_rtc_time));
jsgf855d93d2003-10-13 22:26:55 +00004363 break;
nethercote73b526f2004-10-31 18:48:21 +00004364 case VKI_RTC_ALM_SET:
jsgf855d93d2003-10-13 22:26:55 +00004365 break;
nethercote73b526f2004-10-31 18:48:21 +00004366 case VKI_RTC_IRQP_READ:
njn22cfccb2004-11-27 16:10:23 +00004367 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004368 break;
jsgf855d93d2003-10-13 22:26:55 +00004369
tomeafc49b2005-07-28 16:08:09 +00004370 /* Block devices */
4371 case VKI_BLKROSET:
4372 break;
4373 case VKI_BLKROGET:
4374 POST_MEM_WRITE(ARG3, sizeof(int));
4375 break;
nethercote95a97862004-11-06 16:31:43 +00004376 case VKI_BLKGETSIZE:
njn22cfccb2004-11-27 16:10:23 +00004377 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
jsgf855d93d2003-10-13 22:26:55 +00004378 break;
tomeafc49b2005-07-28 16:08:09 +00004379 case VKI_BLKRASET:
4380 break;
4381 case VKI_BLKRAGET:
4382 POST_MEM_WRITE(ARG3, sizeof(long));
4383 break;
4384 case VKI_BLKFRASET:
4385 break;
4386 case VKI_BLKFRAGET:
4387 POST_MEM_WRITE(ARG3, sizeof(long));
4388 break;
4389 case VKI_BLKSECTGET:
4390 POST_MEM_WRITE(ARG3, sizeof(unsigned short));
4391 break;
4392 case VKI_BLKSSZGET:
4393 POST_MEM_WRITE(ARG3, sizeof(int));
4394 break;
4395 case VKI_BLKBSZGET:
4396 POST_MEM_WRITE(ARG3, sizeof(int));
4397 break;
4398 case VKI_BLKBSZSET:
4399 break;
tomd6555642005-07-18 13:26:55 +00004400 case VKI_BLKGETSIZE64:
4401 POST_MEM_WRITE(ARG3, sizeof(unsigned long long));
4402 break;
jsgf855d93d2003-10-13 22:26:55 +00004403
thughesacbbc322004-06-19 12:12:01 +00004404 /* Hard disks */
tom2c2bc252005-07-28 16:13:42 +00004405 case VKI_HDIO_GETGEO: /* 0x0301 */
4406 POST_MEM_WRITE(ARG3, sizeof(struct vki_hd_geometry));
4407 break;
tom5d2af672006-02-11 13:29:09 +00004408 case VKI_HDIO_GET_DMA: /* 0x030b */
4409 POST_MEM_WRITE(ARG3, sizeof(long));
4410 break;
nethercote73b526f2004-10-31 18:48:21 +00004411 case VKI_HDIO_GET_IDENTITY: /* 0x030d */
njn22cfccb2004-11-27 16:10:23 +00004412 POST_MEM_WRITE(ARG3, VKI_SIZEOF_STRUCT_HD_DRIVEID );
thughesacbbc322004-06-19 12:12:01 +00004413 break;
4414
jsgf855d93d2003-10-13 22:26:55 +00004415 /* CD ROM stuff (??) */
nethercote73b526f2004-10-31 18:48:21 +00004416 case VKI_CDROMSUBCHNL:
njn22cfccb2004-11-27 16:10:23 +00004417 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_subchnl));
jsgf855d93d2003-10-13 22:26:55 +00004418 break;
nethercote73b526f2004-10-31 18:48:21 +00004419 case VKI_CDROMREADTOCHDR:
njn22cfccb2004-11-27 16:10:23 +00004420 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tochdr));
jsgf855d93d2003-10-13 22:26:55 +00004421 break;
nethercote73b526f2004-10-31 18:48:21 +00004422 case VKI_CDROMREADTOCENTRY:
tomf9d83852006-05-08 11:37:04 +00004423 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_tocentry));
jsgf855d93d2003-10-13 22:26:55 +00004424 break;
nethercote73b526f2004-10-31 18:48:21 +00004425 case VKI_CDROMMULTISESSION:
njn22cfccb2004-11-27 16:10:23 +00004426 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_multisession));
thughes5b788fb2004-09-11 15:07:14 +00004427 break;
nethercote73b526f2004-10-31 18:48:21 +00004428 case VKI_CDROMVOLREAD:
njn22cfccb2004-11-27 16:10:23 +00004429 POST_MEM_WRITE(ARG3, sizeof(struct vki_cdrom_volctrl));
thughes5b788fb2004-09-11 15:07:14 +00004430 break;
tomf9d83852006-05-08 11:37:04 +00004431 case VKI_CDROMREADRAW:
4432 POST_MEM_WRITE(ARG3, VKI_CD_FRAMESIZE_RAW);
4433 break;
nethercote73b526f2004-10-31 18:48:21 +00004434 case VKI_CDROMREADAUDIO:
thughes5b788fb2004-09-11 15:07:14 +00004435 {
njn22cfccb2004-11-27 16:10:23 +00004436 struct vki_cdrom_read_audio *cra = (struct vki_cdrom_read_audio *) ARG3;
nethercoteef0c7662004-11-06 15:38:43 +00004437 POST_MEM_WRITE( (Addr)(cra->buf), cra->nframes * VKI_CD_FRAMESIZE_RAW);
thughes5b788fb2004-09-11 15:07:14 +00004438 break;
4439 }
4440
nethercote73b526f2004-10-31 18:48:21 +00004441 case VKI_CDROMPLAYMSF:
jsgf855d93d2003-10-13 22:26:55 +00004442 break;
4443 /* The following two are probably bogus (should check args
4444 for readability). JRS 20021117 */
nethercote73b526f2004-10-31 18:48:21 +00004445 case VKI_CDROM_DRIVE_STATUS: /* 0x5326 */
4446 case VKI_CDROM_CLEAR_OPTIONS: /* 0x5321 */
jsgf855d93d2003-10-13 22:26:55 +00004447 break;
4448
nethercote73b526f2004-10-31 18:48:21 +00004449 case VKI_FIGETBSZ:
njn22cfccb2004-11-27 16:10:23 +00004450 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004451 break;
nethercote73b526f2004-10-31 18:48:21 +00004452 case VKI_FIBMAP:
njn22cfccb2004-11-27 16:10:23 +00004453 POST_MEM_WRITE(ARG3, sizeof(unsigned long));
thughes66d80092004-06-19 12:41:05 +00004454 break;
4455
nethercote73b526f2004-10-31 18:48:21 +00004456 case VKI_FBIOGET_VSCREENINFO: //0x4600
njn22cfccb2004-11-27 16:10:23 +00004457 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_var_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004458 break;
nethercote73b526f2004-10-31 18:48:21 +00004459 case VKI_FBIOGET_FSCREENINFO: //0x4602
njn22cfccb2004-11-27 16:10:23 +00004460 POST_MEM_WRITE(ARG3, sizeof(struct vki_fb_fix_screeninfo));
thughes44e35582004-04-21 15:52:33 +00004461 break;
4462
nethercote73b526f2004-10-31 18:48:21 +00004463 case VKI_PPCLAIM:
4464 case VKI_PPEXCL:
4465 case VKI_PPYIELD:
4466 case VKI_PPRELEASE:
4467 case VKI_PPSETMODE:
4468 case VKI_PPSETPHASE:
4469 case VKI_PPSETFLAGS:
4470 case VKI_PPWDATA:
4471 case VKI_PPWCONTROL:
4472 case VKI_PPFCONTROL:
4473 case VKI_PPDATADIR:
4474 case VKI_PPNEGOT:
4475 case VKI_PPWCTLONIRQ:
4476 case VKI_PPSETTIME:
thughesd9895482004-08-16 19:46:55 +00004477 break;
nethercote73b526f2004-10-31 18:48:21 +00004478 case VKI_PPGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004479 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004480 break;
nethercote73b526f2004-10-31 18:48:21 +00004481 case VKI_PPGETPHASE:
njn22cfccb2004-11-27 16:10:23 +00004482 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004483 break;
nethercote73b526f2004-10-31 18:48:21 +00004484 case VKI_PPGETMODES:
njn22cfccb2004-11-27 16:10:23 +00004485 POST_MEM_WRITE( ARG3, sizeof(unsigned int) );
thughesd9895482004-08-16 19:46:55 +00004486 break;
nethercote73b526f2004-10-31 18:48:21 +00004487 case VKI_PPGETFLAGS:
njn22cfccb2004-11-27 16:10:23 +00004488 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004489 break;
nethercote73b526f2004-10-31 18:48:21 +00004490 case VKI_PPRSTATUS:
njn22cfccb2004-11-27 16:10:23 +00004491 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004492 break;
nethercote73b526f2004-10-31 18:48:21 +00004493 case VKI_PPRDATA:
njn22cfccb2004-11-27 16:10:23 +00004494 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004495 break;
nethercote73b526f2004-10-31 18:48:21 +00004496 case VKI_PPRCONTROL:
njn22cfccb2004-11-27 16:10:23 +00004497 POST_MEM_WRITE( ARG3, sizeof(unsigned char) );
thughesd9895482004-08-16 19:46:55 +00004498 break;
nethercote73b526f2004-10-31 18:48:21 +00004499 case VKI_PPCLRIRQ:
njn22cfccb2004-11-27 16:10:23 +00004500 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesd9895482004-08-16 19:46:55 +00004501 break;
nethercote73b526f2004-10-31 18:48:21 +00004502 case VKI_PPGETTIME:
njn22cfccb2004-11-27 16:10:23 +00004503 POST_MEM_WRITE( ARG3, sizeof(struct vki_timeval) );
thughesd9895482004-08-16 19:46:55 +00004504 break;
4505
thughesc3b842d2004-11-13 10:38:04 +00004506 case VKI_GIO_FONT:
njn22cfccb2004-11-27 16:10:23 +00004507 POST_MEM_WRITE( ARG3, 32 * 256 );
thughesc3b842d2004-11-13 10:38:04 +00004508 break;
4509 case VKI_PIO_FONT:
4510 break;
4511
4512 case VKI_GIO_FONTX:
njn22cfccb2004-11-27 16:10:23 +00004513 POST_MEM_WRITE( (Addr)((struct vki_consolefontdesc *)ARG3)->chardata,
4514 32 * ((struct vki_consolefontdesc *)ARG3)->charcount );
thughesc3b842d2004-11-13 10:38:04 +00004515 break;
4516 case VKI_PIO_FONTX:
4517 break;
4518
4519 case VKI_PIO_FONTRESET:
4520 break;
4521
4522 case VKI_GIO_CMAP:
njn22cfccb2004-11-27 16:10:23 +00004523 POST_MEM_WRITE( ARG3, 16 * 3 );
thughesc3b842d2004-11-13 10:38:04 +00004524 break;
4525 case VKI_PIO_CMAP:
4526 break;
4527
4528 case VKI_KIOCSOUND:
4529 case VKI_KDMKTONE:
4530 break;
4531
4532 case VKI_KDGETLED:
njn22cfccb2004-11-27 16:10:23 +00004533 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004534 break;
4535 case VKI_KDSETLED:
4536 break;
4537
4538 case VKI_KDGKBTYPE:
njn22cfccb2004-11-27 16:10:23 +00004539 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004540 break;
4541
4542 case VKI_KDADDIO:
4543 case VKI_KDDELIO:
4544 case VKI_KDENABIO:
4545 case VKI_KDDISABIO:
4546 break;
4547
4548 case VKI_KDSETMODE:
4549 break;
4550 case VKI_KDGETMODE:
njn22cfccb2004-11-27 16:10:23 +00004551 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004552 break;
4553
4554 case VKI_KDMAPDISP:
4555 case VKI_KDUNMAPDISP:
4556 break;
4557
4558 case VKI_GIO_SCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004559 POST_MEM_WRITE( ARG3, VKI_E_TABSZ );
thughesc3b842d2004-11-13 10:38:04 +00004560 break;
4561 case VKI_PIO_SCRNMAP:
4562 break;
4563 case VKI_GIO_UNISCRNMAP:
njn22cfccb2004-11-27 16:10:23 +00004564 POST_MEM_WRITE( ARG3, VKI_E_TABSZ * sizeof(unsigned short) );
thughesc3b842d2004-11-13 10:38:04 +00004565 break;
4566 case VKI_PIO_UNISCRNMAP:
4567 break;
4568
tom053eb042006-06-07 18:35:34 +00004569 case VKI_GIO_UNIMAP:
4570 if ( ARG3 ) {
4571 struct vki_unimapdesc *desc = (struct vki_unimapdesc *) ARG3;
4572 POST_MEM_WRITE( (Addr)&desc->entry_ct, sizeof(desc->entry_ct));
4573 POST_MEM_WRITE( (Addr)desc->entries,
4574 desc->entry_ct * sizeof(struct vki_unipair) );
4575 }
4576 break;
4577 case VKI_PIO_UNIMAP:
4578 break;
4579 case VKI_PIO_UNIMAPCLR:
4580 break;
4581
thughesc3b842d2004-11-13 10:38:04 +00004582 case VKI_KDGKBMODE:
njn22cfccb2004-11-27 16:10:23 +00004583 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004584 break;
4585 case VKI_KDSKBMODE:
4586 break;
4587
4588 case VKI_KDGKBMETA:
njn22cfccb2004-11-27 16:10:23 +00004589 POST_MEM_WRITE( ARG3, sizeof(int) );
thughesc3b842d2004-11-13 10:38:04 +00004590 break;
4591 case VKI_KDSKBMETA:
4592 break;
4593
4594 case VKI_KDGKBLED:
njn22cfccb2004-11-27 16:10:23 +00004595 POST_MEM_WRITE( ARG3, sizeof(char) );
thughesc3b842d2004-11-13 10:38:04 +00004596 break;
4597 case VKI_KDSKBLED:
4598 break;
4599
4600 case VKI_KDGKBENT:
njn22cfccb2004-11-27 16:10:23 +00004601 POST_MEM_WRITE( (Addr)&((struct vki_kbentry *)ARG3)->kb_value,
4602 sizeof(((struct vki_kbentry *)ARG3)->kb_value) );
thughesc3b842d2004-11-13 10:38:04 +00004603 break;
4604 case VKI_KDSKBENT:
4605 break;
4606
4607 case VKI_KDGKBSENT:
njn22cfccb2004-11-27 16:10:23 +00004608 POST_MEM_WRITE( (Addr)((struct vki_kbsentry *)ARG3)->kb_string,
4609 sizeof(((struct vki_kbsentry *)ARG3)->kb_string) );
thughesc3b842d2004-11-13 10:38:04 +00004610 break;
4611 case VKI_KDSKBSENT:
4612 break;
4613
4614 case VKI_KDGKBDIACR:
njn22cfccb2004-11-27 16:10:23 +00004615 POST_MEM_WRITE( ARG3, sizeof(struct vki_kbdiacrs) );
thughesc3b842d2004-11-13 10:38:04 +00004616 break;
4617 case VKI_KDSKBDIACR:
4618 break;
4619
4620 case VKI_KDGETKEYCODE:
njn22cfccb2004-11-27 16:10:23 +00004621 POST_MEM_WRITE( (Addr)((struct vki_kbkeycode *)ARG3)->keycode,
4622 sizeof(((struct vki_kbkeycode *)ARG3)->keycode) );
thughesc3b842d2004-11-13 10:38:04 +00004623 break;
4624 case VKI_KDSETKEYCODE:
4625 break;
4626
4627 case VKI_KDSIGACCEPT:
4628 break;
4629
4630 case VKI_KDKBDREP:
4631 break;
4632
tom053eb042006-06-07 18:35:34 +00004633 case VKI_KDFONTOP:
4634 if ( ARG3 ) {
4635 struct vki_console_font_op *op = (struct vki_console_font_op *) ARG3;
4636 switch ( op->op ) {
4637 case VKI_KD_FONT_OP_SET:
4638 break;
4639 case VKI_KD_FONT_OP_GET:
4640 if ( op->data )
4641 POST_MEM_WRITE( (Addr) op->data,
4642 (op->width + 7) / 8 * 32 * op->charcount );
4643 break;
4644 case VKI_KD_FONT_OP_SET_DEFAULT:
4645 break;
4646 case VKI_KD_FONT_OP_COPY:
4647 break;
4648 }
4649 POST_MEM_WRITE( (Addr) op, sizeof(*op));
4650 }
4651 break;
4652
4653 case VKI_VT_OPENQRY:
4654 POST_MEM_WRITE( ARG3, sizeof(int) );
4655 break;
4656 case VKI_VT_GETMODE:
4657 POST_MEM_WRITE( ARG3, sizeof(struct vki_vt_mode) );
4658 break;
4659 case VKI_VT_SETMODE:
4660 break;
4661 case VKI_VT_GETSTATE:
4662 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_active),
4663 sizeof(((struct vki_vt_stat*) ARG3)->v_active) );
4664 POST_MEM_WRITE( (Addr) &(((struct vki_vt_stat*) ARG3)->v_state),
4665 sizeof(((struct vki_vt_stat*) ARG3)->v_state) );
4666 break;
4667 case VKI_VT_RELDISP:
4668 case VKI_VT_ACTIVATE:
4669 case VKI_VT_WAITACTIVE:
4670 case VKI_VT_DISALLOCATE:
4671 break;
4672 case VKI_VT_RESIZE:
4673 break;
4674 case VKI_VT_RESIZEX:
4675 break;
4676 case VKI_VT_LOCKSWITCH:
4677 case VKI_VT_UNLOCKSWITCH:
4678 break;
4679
4680
jsgf855d93d2003-10-13 22:26:55 +00004681 /* We don't have any specific information on it, so
4682 try to do something reasonable based on direction and
4683 size bits. The encoding scheme is described in
4684 /usr/include/asm/ioctl.h.
4685
4686 According to Simon Hausmann, _IOC_READ means the kernel
4687 writes a value to the ioctl value passed from the user
4688 space and the other way around with _IOC_WRITE. */
4689 default: {
njn22cfccb2004-11-27 16:10:23 +00004690 UInt dir = _VKI_IOC_DIR(ARG2);
4691 UInt size = _VKI_IOC_SIZE(ARG2);
nethercote73b526f2004-10-31 18:48:21 +00004692 if (size > 0 && (dir & _VKI_IOC_READ)
sewardja8d8e232005-06-07 20:04:56 +00004693 && RES == 0
njn22cfccb2004-11-27 16:10:23 +00004694 && ARG3 != (Addr)NULL)
4695 POST_MEM_WRITE(ARG3, size);
jsgf855d93d2003-10-13 22:26:55 +00004696 break;
4697 }
4698 }
4699}
4700
njn03f1e582005-03-26 20:08:06 +00004701/*
4702 If we're sending a SIGKILL to one of our own threads, then simulate
4703 it rather than really sending the signal, so that the target thread
4704 gets a chance to clean up. Returns True if we did the killing (or
4705 no killing is necessary), and False if the caller should use the
4706 normal kill syscall.
4707
4708 "pid" is any pid argument which can be passed to kill; group kills
4709 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4710 they'll most likely hit all the threads and we won't need to worry
4711 about cleanup. In truth, we can't fully emulate these multicast
4712 kills.
4713
4714 "tgid" is a thread group id. If it is not -1, then the target
4715 thread must be in that thread group.
4716 */
sewardj7eb7c582005-06-23 01:02:53 +00004717Bool ML_(do_sigkill)(Int pid, Int tgid)
njn03f1e582005-03-26 20:08:06 +00004718{
4719 ThreadState *tst;
4720 ThreadId tid;
4721
4722 if (pid <= 0)
4723 return False;
4724
4725 tid = VG_(get_lwp_tid)(pid);
4726 if (tid == VG_INVALID_THREADID)
4727 return False; /* none of our threads */
4728
4729 tst = VG_(get_ThreadState)(tid);
4730 if (tst == NULL || tst->status == VgTs_Empty)
4731 return False; /* hm, shouldn't happen */
4732
4733 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4734 return False; /* not the right thread group */
4735
4736 /* Check to see that the target isn't already exiting. */
4737 if (!VG_(is_exiting)(tid)) {
4738 if (VG_(clo_trace_signals))
sewardja8d8e232005-06-07 20:04:56 +00004739 VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL",
4740 tst->tid);
njn03f1e582005-03-26 20:08:06 +00004741
4742 tst->exitreason = VgSrc_FatalSig;
4743 tst->os_state.fatalsig = VKI_SIGKILL;
4744
4745 if (!VG_(is_running_thread)(tid))
4746 VG_(kill_thread)(tid);
4747 }
4748
4749 return True;
4750}
4751
sewardja8d8e232005-06-07 20:04:56 +00004752PRE(sys_kill)
jsgf855d93d2003-10-13 22:26:55 +00004753{
njn22cfccb2004-11-27 16:10:23 +00004754 PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004755 PRE_REG_READ2(long, "kill", int, pid, int, sig);
sewardj7eb7c582005-06-23 01:02:53 +00004756 if (!ML_(client_signal_OK)(ARG2)) {
sewardja8d8e232005-06-07 20:04:56 +00004757 SET_STATUS_Failure( VKI_EINVAL );
njn03f1e582005-03-26 20:08:06 +00004758 return;
4759 }
jsgf855d93d2003-10-13 22:26:55 +00004760
njn03f1e582005-03-26 20:08:06 +00004761 /* If we're sending SIGKILL, check to see if the target is one of
4762 our threads and handle it specially. */
sewardj7eb7c582005-06-23 01:02:53 +00004763 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
sewardja8d8e232005-06-07 20:04:56 +00004764 SET_STATUS_Success(0);
njn03f1e582005-03-26 20:08:06 +00004765 else
sewardja8d8e232005-06-07 20:04:56 +00004766 SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
njn03f1e582005-03-26 20:08:06 +00004767
sewardjb5f6f512005-03-10 23:59:00 +00004768 if (VG_(clo_trace_signals))
4769 VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
njn03f1e582005-03-26 20:08:06 +00004770 ARG2, ARG1);
sewardja8d8e232005-06-07 20:04:56 +00004771
4772 /* This kill might have given us a pending signal. Ask for a check once
4773 the syscall is done. */
4774 *flags |= SfPollAfter;
jsgf855d93d2003-10-13 22:26:55 +00004775}
4776
sewardja8d8e232005-06-07 20:04:56 +00004777PRE(sys_link)
jsgf855d93d2003-10-13 22:26:55 +00004778{
sewardja8d8e232005-06-07 20:04:56 +00004779 *flags |= SfMayBlock;
tom363ec762006-03-21 10:58:35 +00004780 PRINT("sys_link ( %p(%s), %p(%s) )", ARG1,ARG1,ARG2,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00004781 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00004782 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4783 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
jsgf855d93d2003-10-13 22:26:55 +00004784}
4785
sewardj696c5512005-06-08 23:38:32 +00004786PRE(sys_newlstat)
4787{
4788 PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
4789 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
4790 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4791 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
4792}
4793
4794POST(sys_newlstat)
4795{
4796 vg_assert(SUCCESS);
4797 if (RES == 0) {
4798 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4799 }
4800}
jsgf855d93d2003-10-13 22:26:55 +00004801
sewardja8d8e232005-06-07 20:04:56 +00004802PRE(sys_mkdir)
jsgf855d93d2003-10-13 22:26:55 +00004803{
sewardja8d8e232005-06-07 20:04:56 +00004804 *flags |= SfMayBlock;
tom363ec762006-03-21 10:58:35 +00004805 PRINT("sys_mkdir ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00004806 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00004807 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00004808}
4809
sewardja8d8e232005-06-07 20:04:56 +00004810PRE(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004811{
njn22cfccb2004-11-27 16:10:23 +00004812 PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
nethercote06c7bd72004-11-14 19:11:56 +00004813 PRE_REG_READ3(long, "mprotect",
4814 unsigned long, addr, vki_size_t, len, unsigned long, prot);
fitzhardinge98abfc72003-12-16 02:05:15 +00004815
tom65505192005-11-08 16:51:55 +00004816 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect")) {
sewardja8d8e232005-06-07 20:04:56 +00004817 SET_STATUS_Failure( VKI_ENOMEM );
sewardj337556e2005-11-09 14:51:59 +00004818 }
4819 else
4820 if (ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
4821 /* Deal with mprotects on growable stack areas.
4822
4823 The critical files to understand all this are mm/mprotect.c
4824 in the kernel and sysdeps/unix/sysv/linux/dl-execstack.c in
4825 glibc.
4826
4827 The kernel provides PROT_GROWSDOWN and PROT_GROWSUP which
4828 round the start/end address of mprotect to the start/end of
4829 the underlying vma and glibc uses that as an easy way to
4830 change the protection of the stack by calling mprotect on the
4831 last page of the stack with PROT_GROWSDOWN set.
4832
4833 The sanity check provided by the kernel is that the vma must
4834 have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate. */
tom65505192005-11-08 16:51:55 +00004835 UInt grows = ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
4836 NSegment *aseg = VG_(am_find_nsegment)(ARG1);
4837 NSegment *rseg;
4838
4839 vg_assert(aseg);
4840
4841 if (grows == VKI_PROT_GROWSDOWN) {
4842 rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ );
4843 if (rseg &&
4844 rseg->kind == SkResvn &&
4845 rseg->smode == SmUpper &&
4846 rseg->end+1 == aseg->start) {
4847 Addr end = ARG1 + ARG2;
4848 ARG1 = aseg->start;
4849 ARG2 = end - aseg->start;
4850 ARG3 &= ~VKI_PROT_GROWSDOWN;
4851 } else {
4852 SET_STATUS_Failure( VKI_EINVAL );
4853 }
4854 } else if (grows == VKI_PROT_GROWSUP) {
4855 rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
4856 if (rseg &&
4857 rseg->kind == SkResvn &&
4858 rseg->smode == SmLower &&
4859 aseg->end+1 == rseg->start) {
4860 ARG2 = aseg->end - ARG1 + 1;
4861 ARG3 &= ~VKI_PROT_GROWSUP;
4862 } else {
4863 SET_STATUS_Failure( VKI_EINVAL );
4864 }
4865 } else {
sewardj337556e2005-11-09 14:51:59 +00004866 /* both GROWSUP and GROWSDOWN */
tom65505192005-11-08 16:51:55 +00004867 SET_STATUS_Failure( VKI_EINVAL );
4868 }
4869 }
jsgf855d93d2003-10-13 22:26:55 +00004870}
4871
nethercote85a456f2004-11-16 17:31:56 +00004872POST(sys_mprotect)
jsgf855d93d2003-10-13 22:26:55 +00004873{
njn22cfccb2004-11-27 16:10:23 +00004874 Addr a = ARG1;
4875 SizeT len = ARG2;
4876 Int prot = ARG3;
sewardj45f4e7c2005-09-27 19:20:21 +00004877 Bool rr = toBool(prot & VKI_PROT_READ);
4878 Bool ww = toBool(prot & VKI_PROT_WRITE);
4879 Bool xx = toBool(prot & VKI_PROT_EXEC);
4880 Bool d;
nethercote27ea8bc2004-07-10 17:21:14 +00004881
sewardj45f4e7c2005-09-27 19:20:21 +00004882 page_align_addr_and_len(&a, &len);
4883 d = VG_(am_notify_mprotect)(a, len, prot);
nethercote27ea8bc2004-07-10 17:21:14 +00004884 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
sewardj45f4e7c2005-09-27 19:20:21 +00004885 VG_(di_notify_mprotect)( a, len, prot );
4886 if (d)
4887 VG_(discard_translations)( (Addr64)a, (ULong)len,
4888 "POST(sys_mprotect)" );
jsgf855d93d2003-10-13 22:26:55 +00004889}
4890
sewardja8d8e232005-06-07 20:04:56 +00004891PRE(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004892{
sewardja8d8e232005-06-07 20:04:56 +00004893 if (0) VG_(printf)(" munmap( %p )\n", ARG1);
njn22cfccb2004-11-27 16:10:23 +00004894 PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
nethercote06c7bd72004-11-14 19:11:56 +00004895 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
fitzhardinge98abfc72003-12-16 02:05:15 +00004896
sewardj7eb7c582005-06-23 01:02:53 +00004897 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
sewardja8d8e232005-06-07 20:04:56 +00004898 SET_STATUS_Failure( VKI_EINVAL );
jsgf855d93d2003-10-13 22:26:55 +00004899}
4900
nethercote85a456f2004-11-16 17:31:56 +00004901POST(sys_munmap)
jsgf855d93d2003-10-13 22:26:55 +00004902{
njn22cfccb2004-11-27 16:10:23 +00004903 Addr a = ARG1;
4904 SizeT len = ARG2;
sewardj45f4e7c2005-09-27 19:20:21 +00004905 Bool d;
nethercote27ea8bc2004-07-10 17:21:14 +00004906
sewardj45f4e7c2005-09-27 19:20:21 +00004907 page_align_addr_and_len(&a, &len);
4908 d = VG_(am_notify_munmap)(a, len);
nethercote27ea8bc2004-07-10 17:21:14 +00004909 VG_TRACK( die_mem_munmap, a, len );
sewardj45f4e7c2005-09-27 19:20:21 +00004910 VG_(di_notify_munmap)( a, len );
4911 if (d)
4912 VG_(discard_translations)( (Addr64)a, (ULong)len,
4913 "POST(sys_munmap)" );
jsgf855d93d2003-10-13 22:26:55 +00004914}
4915
sewardje6d5e722005-06-10 10:27:55 +00004916PRE(sys_mincore)
4917{
4918 PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
4919 PRE_REG_READ3(long, "mincore",
4920 unsigned long, start, vki_size_t, length,
4921 unsigned char *, vec);
njncdaec512005-06-30 00:16:02 +00004922 PRE_MEM_WRITE( "mincore(vec)", ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
sewardje6d5e722005-06-10 10:27:55 +00004923}
4924POST(sys_mincore)
4925{
njncdaec512005-06-30 00:16:02 +00004926 POST_MEM_WRITE( ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
sewardje6d5e722005-06-10 10:27:55 +00004927}
mueller6ceb2312004-01-02 22:52:34 +00004928
sewardja8d8e232005-06-07 20:04:56 +00004929PRE(sys_nanosleep)
mueller6ceb2312004-01-02 22:52:34 +00004930{
sewardja8d8e232005-06-07 20:04:56 +00004931 *flags |= SfMayBlock|SfPostOnFail;
njn22cfccb2004-11-27 16:10:23 +00004932 PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
nethercote5b653bc2004-11-15 14:32:12 +00004933 PRE_REG_READ2(long, "nanosleep",
4934 struct timespec *, req, struct timespec *, rem);
njn22cfccb2004-11-27 16:10:23 +00004935 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4936 if (ARG2 != 0)
4937 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004938}
4939
nethercote85a456f2004-11-16 17:31:56 +00004940POST(sys_nanosleep)
jsgf855d93d2003-10-13 22:26:55 +00004941{
sewardja8d8e232005-06-07 20:04:56 +00004942 vg_assert(SUCCESS || FAILURE);
4943 if (ARG2 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
njn22cfccb2004-11-27 16:10:23 +00004944 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
jsgf855d93d2003-10-13 22:26:55 +00004945}
4946
sewardja8d8e232005-06-07 20:04:56 +00004947PRE(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004948{
sewardj45f4e7c2005-09-27 19:20:21 +00004949 HChar name[30];
4950 SysRes sres;
4951
njn22cfccb2004-11-27 16:10:23 +00004952 if (ARG2 & VKI_O_CREAT) {
nethercotee824cc42004-11-09 16:20:46 +00004953 // 3-arg version
njn22cfccb2004-11-27 16:10:23 +00004954 PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
nethercotee824cc42004-11-09 16:20:46 +00004955 PRE_REG_READ3(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004956 const char *, filename, int, flags, int, mode);
nethercotee70bd7d2004-08-18 14:37:17 +00004957 } else {
nethercotee824cc42004-11-09 16:20:46 +00004958 // 2-arg version
njn22cfccb2004-11-27 16:10:23 +00004959 PRINT("sys_open ( %p(%s), %d )",ARG1,ARG1,ARG2);
nethercotee824cc42004-11-09 16:20:46 +00004960 PRE_REG_READ2(long, "open",
nethercote0df495a2004-11-11 16:38:21 +00004961 const char *, filename, int, flags);
nethercotee70bd7d2004-08-18 14:37:17 +00004962 }
njn22cfccb2004-11-27 16:10:23 +00004963 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
sewardj45f4e7c2005-09-27 19:20:21 +00004964
4965 /* Handle the case where the open is of /proc/self/cmdline or
4966 /proc/<pid>/cmdline, and just give it a copy of the fd for the
4967 fake file we cooked up at startup (in m_main). Also, seek the
4968 cloned fd back to the start. */
4969
4970 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
4971 if (ML_(safe_to_deref)( (void*)ARG1, 1 )
4972 && (VG_(strcmp)((Char *)ARG1, name) == 0
4973 || VG_(strcmp)((Char *)ARG1, "/proc/self/cmdline") == 0)) {
4974 sres = VG_(dup)( VG_(cl_cmdline_fd) );
4975 SET_STATUS_from_SysRes( sres );
4976 if (!sres.isError) {
4977 OffT off = VG_(lseek)( sres.val, 0, VKI_SEEK_SET );
tomf4c23102005-10-31 17:05:21 +00004978 if (off < 0)
sewardj45f4e7c2005-09-27 19:20:21 +00004979 SET_STATUS_Failure( VKI_EMFILE );
4980 }
4981 return;
4982 }
4983
4984 /* Otherwise handle normally */
4985 *flags |= SfMayBlock;
jsgf855d93d2003-10-13 22:26:55 +00004986}
4987
nethercote85a456f2004-11-16 17:31:56 +00004988POST(sys_open)
jsgf855d93d2003-10-13 22:26:55 +00004989{
sewardja8d8e232005-06-07 20:04:56 +00004990 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00004991 if (!ML_(fd_allowed)(RES, "open", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00004992 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00004993 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00004994 } else {
nethercote493dd182004-02-24 23:57:47 +00004995 if (VG_(clo_track_fds))
njn4279a882005-08-26 03:43:28 +00004996 ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
jsgf855d93d2003-10-13 22:26:55 +00004997 }
jsgf855d93d2003-10-13 22:26:55 +00004998}
4999
sewardja8d8e232005-06-07 20:04:56 +00005000PRE(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00005001{
sewardja8d8e232005-06-07 20:04:56 +00005002 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005003 PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00005004 PRE_REG_READ3(ssize_t, "read",
njnca0518d2004-11-26 19:34:36 +00005005 unsigned int, fd, char *, buf, vki_size_t, count);
jsgf855d93d2003-10-13 22:26:55 +00005006
sewardj7eb7c582005-06-23 01:02:53 +00005007 if (!ML_(fd_allowed)(ARG1, "read", tid, False))
sewardja8d8e232005-06-07 20:04:56 +00005008 SET_STATUS_Failure( VKI_EBADF );
thughes26ab77b2004-08-14 12:10:49 +00005009 else
njn22cfccb2004-11-27 16:10:23 +00005010 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00005011}
5012
nethercote85a456f2004-11-16 17:31:56 +00005013POST(sys_read)
jsgf855d93d2003-10-13 22:26:55 +00005014{
sewardja8d8e232005-06-07 20:04:56 +00005015 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005016 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00005017}
5018
sewardja8d8e232005-06-07 20:04:56 +00005019PRE(sys_write)
jsgf855d93d2003-10-13 22:26:55 +00005020{
sewardj45f4e7c2005-09-27 19:20:21 +00005021 Bool ok;
sewardja8d8e232005-06-07 20:04:56 +00005022 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005023 PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
nethercote8b76fe52004-11-08 19:20:09 +00005024 PRE_REG_READ3(ssize_t, "write",
njnca0518d2004-11-26 19:34:36 +00005025 unsigned int, fd, const char *, buf, vki_size_t, count);
sewardj45f4e7c2005-09-27 19:20:21 +00005026 /* check to see if it is allowed. If not, try for an exemption from
njn628add62005-11-12 18:21:40 +00005027 --sim-hints=enable-outer (used for self hosting). */
sewardj45f4e7c2005-09-27 19:20:21 +00005028 ok = ML_(fd_allowed)(ARG1, "write", tid, False);
5029 if (!ok && ARG1 == 2/*stderr*/
njn628add62005-11-12 18:21:40 +00005030 && VG_(strstr)(VG_(clo_sim_hints),"enable-outer"))
sewardj45f4e7c2005-09-27 19:20:21 +00005031 ok = True;
5032 if (!ok)
sewardja8d8e232005-06-07 20:04:56 +00005033 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005034 else
njn22cfccb2004-11-27 16:10:23 +00005035 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00005036}
5037
sewardja8d8e232005-06-07 20:04:56 +00005038PRE(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00005039{
sewardja8d8e232005-06-07 20:04:56 +00005040 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005041 PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
nethercotec6851dd2004-11-11 18:00:47 +00005042 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
njn22cfccb2004-11-27 16:10:23 +00005043 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00005044}
5045
nethercote85a456f2004-11-16 17:31:56 +00005046POST(sys_creat)
jsgf855d93d2003-10-13 22:26:55 +00005047{
sewardja8d8e232005-06-07 20:04:56 +00005048 vg_assert(SUCCESS);
sewardj7eb7c582005-06-23 01:02:53 +00005049 if (!ML_(fd_allowed)(RES, "creat", tid, True)) {
njn22cfccb2004-11-27 16:10:23 +00005050 VG_(close)(RES);
sewardja8d8e232005-06-07 20:04:56 +00005051 SET_STATUS_Failure( VKI_EMFILE );
rjwalshf5f536f2003-11-17 17:45:00 +00005052 } else {
nethercote493dd182004-02-24 23:57:47 +00005053 if (VG_(clo_track_fds))
njn4279a882005-08-26 03:43:28 +00005054 ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
jsgf855d93d2003-10-13 22:26:55 +00005055 }
jsgf855d93d2003-10-13 22:26:55 +00005056}
5057
sewardja8d8e232005-06-07 20:04:56 +00005058PRE(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00005059{
5060 /* struct pollfd {
nethercoteef0c7662004-11-06 15:38:43 +00005061 int fd; -- file descriptor
5062 short events; -- requested events
5063 short revents; -- returned events
jsgf855d93d2003-10-13 22:26:55 +00005064 };
nethercoteeb0592d2004-11-05 12:02:27 +00005065 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
jsgf855d93d2003-10-13 22:26:55 +00005066 */
nethercoteeb0592d2004-11-05 12:02:27 +00005067 UInt i;
njn22cfccb2004-11-27 16:10:23 +00005068 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
tom60a4b0b2005-10-12 10:45:27 +00005069 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005070 PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
nethercotef90953e2004-11-15 14:50:02 +00005071 PRE_REG_READ3(long, "poll",
tom363ec762006-03-21 10:58:35 +00005072 struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout);
5073
njn22cfccb2004-11-27 16:10:23 +00005074 for (i = 0; i < ARG2; i++) {
tom363ec762006-03-21 10:58:35 +00005075 PRE_MEM_READ( "poll(ufds.fd)",
5076 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
5077 PRE_MEM_READ( "poll(ufds.events)",
5078 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
sewardjeb662fa2006-03-22 11:18:50 +00005079 PRE_MEM_WRITE( "poll(ufds.reventss)",
tom363ec762006-03-21 10:58:35 +00005080 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
5081 }
jsgf855d93d2003-10-13 22:26:55 +00005082}
5083
nethercote85a456f2004-11-16 17:31:56 +00005084POST(sys_poll)
jsgf855d93d2003-10-13 22:26:55 +00005085{
njn22cfccb2004-11-27 16:10:23 +00005086 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00005087 UInt i;
njn22cfccb2004-11-27 16:10:23 +00005088 struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
njn22cfccb2004-11-27 16:10:23 +00005089 for (i = 0; i < ARG2; i++)
tom363ec762006-03-21 10:58:35 +00005090 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
jsgf855d93d2003-10-13 22:26:55 +00005091 }
5092}
5093
sewardja8d8e232005-06-07 20:04:56 +00005094PRE(sys_readlink)
jsgf855d93d2003-10-13 22:26:55 +00005095{
sewardj144c56d2005-09-30 01:09:50 +00005096 HChar name[25];
5097 Word saved = SYSNO;
5098
tom363ec762006-03-21 10:58:35 +00005099 PRINT("sys_readlink ( %p(%s), %p, %llu )", ARG1,ARG1,ARG2,(ULong)ARG3);
nethercote5a945af2004-11-14 18:37:07 +00005100 PRE_REG_READ3(long, "readlink",
5101 const char *, path, char *, buf, int, bufsiz);
njn22cfccb2004-11-27 16:10:23 +00005102 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
5103 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
jsgf855d93d2003-10-13 22:26:55 +00005104
rjwalsh17d85302004-11-18 22:56:09 +00005105 /*
rjwalsh093047d2004-11-19 02:11:56 +00005106 * Handle the case where readlink is looking at /proc/self/exe or
5107 * /proc/<pid>/exe.
rjwalsh17d85302004-11-18 22:56:09 +00005108 */
sewardj144c56d2005-09-30 01:09:50 +00005109 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
sewardjca7a4752005-09-30 10:32:39 +00005110 if (ML_(safe_to_deref)((void*)ARG1, 1)
sewardje226b382005-09-30 01:47:12 +00005111 && (VG_(strcmp)((Char *)ARG1, name) == 0
5112 || VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0)) {
sewardj144c56d2005-09-30 01:09:50 +00005113 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
5114 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name,
5115 ARG2, ARG3));
5116 } else {
5117 /* Normal case */
5118 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
rjwalsh17d85302004-11-18 22:56:09 +00005119 }
5120
sewardja8d8e232005-06-07 20:04:56 +00005121 if (SUCCESS && RES > 0)
njn22cfccb2004-11-27 16:10:23 +00005122 POST_MEM_WRITE( ARG2, RES );
jsgf855d93d2003-10-13 22:26:55 +00005123}
5124
sewardja8d8e232005-06-07 20:04:56 +00005125PRE(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00005126{
jsgf855d93d2003-10-13 22:26:55 +00005127 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005128 struct vki_iovec * vec;
sewardja8d8e232005-06-07 20:04:56 +00005129 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005130 PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005131 PRE_REG_READ3(ssize_t, "readv",
5132 unsigned long, fd, const struct iovec *, vector,
5133 unsigned long, count);
sewardj7eb7c582005-06-23 01:02:53 +00005134 if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
sewardja8d8e232005-06-07 20:04:56 +00005135 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005136 } else {
njn22cfccb2004-11-27 16:10:23 +00005137 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
nethercoted6b5a212004-11-15 17:04:14 +00005138
njn22cfccb2004-11-27 16:10:23 +00005139 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005140 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005141 vec = (struct vki_iovec *)ARG2;
5142 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005143 PRE_MEM_WRITE( "readv(vector[...])",
5144 (Addr)vec[i].iov_base, vec[i].iov_len );
5145 }
jsgf855d93d2003-10-13 22:26:55 +00005146 }
5147}
5148
nethercote85a456f2004-11-16 17:31:56 +00005149POST(sys_readv)
jsgf855d93d2003-10-13 22:26:55 +00005150{
sewardja8d8e232005-06-07 20:04:56 +00005151 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005152 if (RES > 0) {
jsgf855d93d2003-10-13 22:26:55 +00005153 Int i;
njn22cfccb2004-11-27 16:10:23 +00005154 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
5155 Int remains = RES;
jsgf855d93d2003-10-13 22:26:55 +00005156
njn22cfccb2004-11-27 16:10:23 +00005157 /* RES holds the number of bytes read. */
5158 for (i = 0; i < (Int)ARG3; i++) {
jsgf855d93d2003-10-13 22:26:55 +00005159 Int nReadThisBuf = vec[i].iov_len;
5160 if (nReadThisBuf > remains) nReadThisBuf = remains;
nethercoteef0c7662004-11-06 15:38:43 +00005161 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
jsgf855d93d2003-10-13 22:26:55 +00005162 remains -= nReadThisBuf;
5163 if (remains < 0) VG_(core_panic)("readv: remains < 0");
5164 }
5165 }
5166}
5167
sewardja8d8e232005-06-07 20:04:56 +00005168PRE(sys_rename)
jsgf855d93d2003-10-13 22:26:55 +00005169{
tom363ec762006-03-21 10:58:35 +00005170 PRINT("sys_rename ( %p(%s), %p(%s) )", ARG1,ARG1,ARG2,ARG2);
nethercote9a3beb92004-11-12 17:07:26 +00005171 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
njn22cfccb2004-11-27 16:10:23 +00005172 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
5173 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
jsgf855d93d2003-10-13 22:26:55 +00005174}
5175
sewardj78b50e42005-06-08 01:47:28 +00005176PRE(sys_rmdir)
5177{
5178 *flags |= SfMayBlock;
tom363ec762006-03-21 10:58:35 +00005179 PRINT("sys_rmdir ( %p(%s) )", ARG1,ARG1);
sewardj78b50e42005-06-08 01:47:28 +00005180 PRE_REG_READ1(long, "rmdir", const char *, pathname);
5181 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
5182}
5183
sewardja8d8e232005-06-07 20:04:56 +00005184PRE(sys_select)
jsgf855d93d2003-10-13 22:26:55 +00005185{
sewardja8d8e232005-06-07 20:04:56 +00005186 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005187 PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
nethercotef1049bf2004-11-14 17:03:47 +00005188 PRE_REG_READ5(long, "select",
5189 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
tom363ec762006-03-21 10:58:35 +00005190 vki_fd_set *, exceptfds, struct vki_timeval *, timeout);
nethercotef1049bf2004-11-14 17:03:47 +00005191 // XXX: this possibly understates how much memory is read.
njn22cfccb2004-11-27 16:10:23 +00005192 if (ARG2 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00005193 PRE_MEM_READ( "select(readfds)",
njn22cfccb2004-11-27 16:10:23 +00005194 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
5195 if (ARG3 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00005196 PRE_MEM_READ( "select(writefds)",
njn22cfccb2004-11-27 16:10:23 +00005197 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
5198 if (ARG4 != 0)
nethercotef1049bf2004-11-14 17:03:47 +00005199 PRE_MEM_READ( "select(exceptfds)",
njn22cfccb2004-11-27 16:10:23 +00005200 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
5201 if (ARG5 != 0)
5202 PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
nethercotef1049bf2004-11-14 17:03:47 +00005203}
5204
sewardje6d5e722005-06-10 10:27:55 +00005205PRE(sys_setgid)
5206{
5207 PRINT("sys_setgid ( %d )", ARG1);
5208 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
5209}
sewardj696c5512005-06-08 23:38:32 +00005210
5211PRE(sys_setsid)
5212{
5213 PRINT("sys_setsid ( )");
5214 PRE_REG_READ0(long, "setsid");
5215}
5216
sewardje6d5e722005-06-10 10:27:55 +00005217PRE(sys_setgroups)
5218{
5219 PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
5220 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
5221 if (ARG1 > 0)
5222 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
5223}
sewardj696c5512005-06-08 23:38:32 +00005224
5225PRE(sys_setpgid)
5226{
5227 PRINT("setpgid ( %d, %d )", ARG1, ARG2);
5228 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
5229}
5230
5231PRE(sys_setregid)
5232{
5233 PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
5234 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
5235}
5236
sewardje6d5e722005-06-10 10:27:55 +00005237PRE(sys_setreuid)
5238{
5239 PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
5240 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
5241}
nethercote9c311eb2004-11-12 18:20:12 +00005242
sewardja8d8e232005-06-07 20:04:56 +00005243PRE(sys_setrlimit)
jsgf855d93d2003-10-13 22:26:55 +00005244{
njn22cfccb2004-11-27 16:10:23 +00005245 PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
nethercote17258dc2004-11-12 19:55:08 +00005246 PRE_REG_READ2(long, "setrlimit",
5247 unsigned int, resource, struct rlimit *, rlim);
njn22cfccb2004-11-27 16:10:23 +00005248 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
fitzhardingeb50068f2004-02-24 23:42:55 +00005249
njn22cfccb2004-11-27 16:10:23 +00005250 if (ARG1 == VKI_RLIMIT_NOFILE) {
5251 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
5252 ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
sewardja8d8e232005-06-07 20:04:56 +00005253 SET_STATUS_Failure( VKI_EPERM );
thughesad1c9562004-06-26 11:27:52 +00005254 }
5255 else {
njn22cfccb2004-11-27 16:10:23 +00005256 VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
sewardja8d8e232005-06-07 20:04:56 +00005257 SET_STATUS_Success( 0 );
thughesad1c9562004-06-26 11:27:52 +00005258 }
5259 }
njn22cfccb2004-11-27 16:10:23 +00005260 else if (ARG1 == VKI_RLIMIT_DATA) {
tomae0739d2006-03-20 15:36:28 +00005261 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(client_rlimit_data).rlim_max ||
5262 ((struct vki_rlimit *)ARG2)->rlim_max > VG_(client_rlimit_data).rlim_max) {
sewardja8d8e232005-06-07 20:04:56 +00005263 SET_STATUS_Failure( VKI_EPERM );
thughesaa4fb112004-09-11 14:19:25 +00005264 }
5265 else {
njn22cfccb2004-11-27 16:10:23 +00005266 VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
sewardja8d8e232005-06-07 20:04:56 +00005267 SET_STATUS_Success( 0 );
thughesaa4fb112004-09-11 14:19:25 +00005268 }
fitzhardingeb50068f2004-02-24 23:42:55 +00005269 }
njn22cfccb2004-11-27 16:10:23 +00005270 else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
tomae0739d2006-03-20 15:36:28 +00005271 if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(client_rlimit_stack).rlim_max ||
5272 ((struct vki_rlimit *)ARG2)->rlim_max > VG_(client_rlimit_stack).rlim_max) {
sewardja8d8e232005-06-07 20:04:56 +00005273 SET_STATUS_Failure( VKI_EPERM );
thughesc37184f2004-09-11 14:16:57 +00005274 }
5275 else {
sewardja8d8e232005-06-07 20:04:56 +00005276 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
njn22cfccb2004-11-27 16:10:23 +00005277 VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
sewardja8d8e232005-06-07 20:04:56 +00005278 SET_STATUS_Success( 0 );
thughesc37184f2004-09-11 14:16:57 +00005279 }
5280 }
jsgf855d93d2003-10-13 22:26:55 +00005281}
5282
sewardje6d5e722005-06-10 10:27:55 +00005283PRE(sys_setuid)
5284{
5285 PRINT("sys_setuid ( %d )", ARG1);
5286 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
5287}
jsgf855d93d2003-10-13 22:26:55 +00005288
sewardj696c5512005-06-08 23:38:32 +00005289PRE(sys_newstat)
5290{
5291 PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
5292 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
5293 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
5294 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
5295}
5296
5297POST(sys_newstat)
5298{
5299 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
5300}
5301
5302PRE(sys_statfs)
5303{
tom363ec762006-03-21 10:58:35 +00005304 PRINT("sys_statfs ( %p(%s), %p )",ARG1,ARG1,ARG2);
sewardj696c5512005-06-08 23:38:32 +00005305 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
5306 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
5307 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
5308}
sewardj696c5512005-06-08 23:38:32 +00005309POST(sys_statfs)
5310{
5311 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
5312}
5313
sewardje6d5e722005-06-10 10:27:55 +00005314PRE(sys_statfs64)
5315{
tom363ec762006-03-21 10:58:35 +00005316 PRINT("sys_statfs64 ( %p(%s), %llu, %p )",ARG1,ARG1,(ULong)ARG2,ARG3);
sewardje6d5e722005-06-10 10:27:55 +00005317 PRE_REG_READ3(long, "statfs64",
5318 const char *, path, vki_size_t, size, struct statfs64 *, buf);
5319 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
5320 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
5321}
5322POST(sys_statfs64)
5323{
5324 POST_MEM_WRITE( ARG3, ARG2 );
5325}
sewardj78b50e42005-06-08 01:47:28 +00005326
5327PRE(sys_symlink)
5328{
5329 *flags |= SfMayBlock;
tom363ec762006-03-21 10:58:35 +00005330 PRINT("sys_symlink ( %p(%s), %p(%s) )",ARG1,ARG1,ARG2,ARG2);
sewardj78b50e42005-06-08 01:47:28 +00005331 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
5332 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
5333 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
5334}
sewardj9efbbef2005-03-01 16:45:23 +00005335
sewardja8d8e232005-06-07 20:04:56 +00005336PRE(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005337{
5338 /* time_t time(time_t *t); */
njn22cfccb2004-11-27 16:10:23 +00005339 PRINT("sys_time ( %p )",ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005340 PRE_REG_READ1(long, "time", int *, t);
njn22cfccb2004-11-27 16:10:23 +00005341 if (ARG1 != 0) {
5342 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005343 }
5344}
5345
nethercote85a456f2004-11-16 17:31:56 +00005346POST(sys_time)
jsgf855d93d2003-10-13 22:26:55 +00005347{
njn22cfccb2004-11-27 16:10:23 +00005348 if (ARG1 != 0) {
5349 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
jsgf855d93d2003-10-13 22:26:55 +00005350 }
5351}
5352
sewardj78b50e42005-06-08 01:47:28 +00005353PRE(sys_times)
5354{
5355 PRINT("sys_times ( %p )", ARG1);
5356 PRE_REG_READ1(long, "times", struct tms *, buf);
tom18f19272005-07-18 11:03:35 +00005357 if (ARG1 != 0) {
5358 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
5359 }
sewardj78b50e42005-06-08 01:47:28 +00005360}
5361
5362POST(sys_times)
5363{
5364 if (ARG1 != 0) {
5365 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
5366 }
5367}
5368
5369PRE(sys_umask)
5370{
5371 PRINT("sys_umask ( %d )", ARG1);
5372 PRE_REG_READ1(long, "umask", int, mask);
5373}
jsgf855d93d2003-10-13 22:26:55 +00005374
sewardja8d8e232005-06-07 20:04:56 +00005375PRE(sys_unlink)
jsgf855d93d2003-10-13 22:26:55 +00005376{
sewardja8d8e232005-06-07 20:04:56 +00005377 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005378 PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
nethercotec6851dd2004-11-11 18:00:47 +00005379 PRE_REG_READ1(long, "unlink", const char *, pathname);
njn22cfccb2004-11-27 16:10:23 +00005380 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
jsgf855d93d2003-10-13 22:26:55 +00005381}
5382
sewardja8d8e232005-06-07 20:04:56 +00005383PRE(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005384{
njn22cfccb2004-11-27 16:10:23 +00005385 PRINT("sys_newuname ( %p )", ARG1);
nethercote1a1b9b72004-11-12 11:19:36 +00005386 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
njn22cfccb2004-11-27 16:10:23 +00005387 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005388}
5389
nethercote85a456f2004-11-16 17:31:56 +00005390POST(sys_newuname)
jsgf855d93d2003-10-13 22:26:55 +00005391{
njn22cfccb2004-11-27 16:10:23 +00005392 if (ARG1 != 0) {
5393 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
jsgf855d93d2003-10-13 22:26:55 +00005394 }
5395}
5396
sewardja8d8e232005-06-07 20:04:56 +00005397PRE(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005398{
sewardja8d8e232005-06-07 20:04:56 +00005399 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005400 PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
nethercotec6851dd2004-11-11 18:00:47 +00005401 PRE_REG_READ3(long, "waitpid",
5402 vki_pid_t, pid, unsigned int *, status, int, options);
jsgf855d93d2003-10-13 22:26:55 +00005403
njn22cfccb2004-11-27 16:10:23 +00005404 if (ARG2 != (Addr)NULL)
5405 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005406}
5407
nethercote85a456f2004-11-16 17:31:56 +00005408POST(sys_waitpid)
jsgf855d93d2003-10-13 22:26:55 +00005409{
njn22cfccb2004-11-27 16:10:23 +00005410 if (ARG2 != (Addr)NULL)
5411 POST_MEM_WRITE( ARG2, sizeof(int) );
jsgf855d93d2003-10-13 22:26:55 +00005412}
5413
sewardja8d8e232005-06-07 20:04:56 +00005414PRE(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005415{
sewardja8d8e232005-06-07 20:04:56 +00005416 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005417 PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
jsgf855d93d2003-10-13 22:26:55 +00005418
nethercote7f7e4d12004-11-15 12:28:58 +00005419 PRE_REG_READ4(long, "wait4",
5420 vki_pid_t, pid, unsigned int *, status, int, options,
5421 struct rusage *, rusage);
njn22cfccb2004-11-27 16:10:23 +00005422 if (ARG2 != (Addr)NULL)
5423 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
5424 if (ARG4 != (Addr)NULL)
5425 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005426}
5427
nethercote85a456f2004-11-16 17:31:56 +00005428POST(sys_wait4)
jsgf855d93d2003-10-13 22:26:55 +00005429{
njn22cfccb2004-11-27 16:10:23 +00005430 if (ARG2 != (Addr)NULL)
5431 POST_MEM_WRITE( ARG2, sizeof(int) );
5432 if (ARG4 != (Addr)NULL)
5433 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
jsgf855d93d2003-10-13 22:26:55 +00005434}
5435
sewardja8d8e232005-06-07 20:04:56 +00005436PRE(sys_writev)
jsgf855d93d2003-10-13 22:26:55 +00005437{
jsgf855d93d2003-10-13 22:26:55 +00005438 Int i;
nethercote73b526f2004-10-31 18:48:21 +00005439 struct vki_iovec * vec;
sewardja8d8e232005-06-07 20:04:56 +00005440 *flags |= SfMayBlock;
njn22cfccb2004-11-27 16:10:23 +00005441 PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
nethercoted6b5a212004-11-15 17:04:14 +00005442 PRE_REG_READ3(ssize_t, "writev",
5443 unsigned long, fd, const struct iovec *, vector,
5444 unsigned long, count);
sewardj7eb7c582005-06-23 01:02:53 +00005445 if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) {
sewardja8d8e232005-06-07 20:04:56 +00005446 SET_STATUS_Failure( VKI_EBADF );
jsgf855d93d2003-10-13 22:26:55 +00005447 } else {
nethercoteef0c7662004-11-06 15:38:43 +00005448 PRE_MEM_READ( "writev(vector)",
njn22cfccb2004-11-27 16:10:23 +00005449 ARG2, ARG3 * sizeof(struct vki_iovec) );
5450 if (ARG2 != 0) {
nethercoted6b5a212004-11-15 17:04:14 +00005451 /* ToDo: don't do any of the following if the vector is invalid */
njn22cfccb2004-11-27 16:10:23 +00005452 vec = (struct vki_iovec *)ARG2;
5453 for (i = 0; i < (Int)ARG3; i++)
nethercoted6b5a212004-11-15 17:04:14 +00005454 PRE_MEM_READ( "writev(vector[...])",
5455 (Addr)vec[i].iov_base, vec[i].iov_len );
5456 }
jsgf855d93d2003-10-13 22:26:55 +00005457 }
5458}
5459
sewardje6d5e722005-06-10 10:27:55 +00005460PRE(sys_utimes)
5461{
tom363ec762006-03-21 10:58:35 +00005462 PRINT("sys_utimes ( %p(%s), %p )", ARG1,ARG1,ARG2);
sewardje6d5e722005-06-10 10:27:55 +00005463 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
5464 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5465 if (ARG2 != 0)
5466 PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
5467}
5468
sewardj696c5512005-06-08 23:38:32 +00005469PRE(sys_acct)
5470{
tom363ec762006-03-21 10:58:35 +00005471 PRINT("sys_acct ( %p(%s) )", ARG1,ARG1);
sewardj696c5512005-06-08 23:38:32 +00005472 PRE_REG_READ1(long, "acct", const char *, filename);
5473 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
5474}
muellerd3502b62003-11-19 00:43:57 +00005475
sewardja8d8e232005-06-07 20:04:56 +00005476PRE(sys_pause)
thughes2f8d5f82004-09-11 14:29:19 +00005477{
sewardja8d8e232005-06-07 20:04:56 +00005478 *flags |= SfMayBlock;
nethercote0df495a2004-11-11 16:38:21 +00005479 PRINT("sys_pause ( )");
5480 PRE_REG_READ0(long, "pause");
jsgf855d93d2003-10-13 22:26:55 +00005481}
5482
nethercotea3a2c142004-11-14 14:13:05 +00005483// XXX: x86-specific
sewardja8d8e232005-06-07 20:04:56 +00005484PRE(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005485{
njn22cfccb2004-11-27 16:10:23 +00005486 PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
nethercoteb77dee62004-11-16 17:13:24 +00005487 PRE_REG_READ2(int, "sigaltstack",
5488 const vki_stack_t *, ss, vki_stack_t *, oss);
njn22cfccb2004-11-27 16:10:23 +00005489 if (ARG1 != 0) {
tom92098db2005-07-18 23:18:10 +00005490 const vki_stack_t *ss = (vki_stack_t *)ARG1;
5491 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_sp, sizeof(ss->ss_sp) );
5492 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_flags, sizeof(ss->ss_flags) );
5493 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_size, sizeof(ss->ss_size) );
jsgf855d93d2003-10-13 22:26:55 +00005494 }
njn22cfccb2004-11-27 16:10:23 +00005495 if (ARG2 != 0) {
5496 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
jsgf855d93d2003-10-13 22:26:55 +00005497 }
5498
sewardja8d8e232005-06-07 20:04:56 +00005499 SET_STATUS_from_SysRes(
5500 VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1,
5501 (vki_stack_t*)ARG2)
5502 );
jsgf855d93d2003-10-13 22:26:55 +00005503}
nethercote85a456f2004-11-16 17:31:56 +00005504POST(sys_sigaltstack)
jsgf855d93d2003-10-13 22:26:55 +00005505{
sewardja8d8e232005-06-07 20:04:56 +00005506 vg_assert(SUCCESS);
njn22cfccb2004-11-27 16:10:23 +00005507 if (RES == 0 && ARG2 != 0)
5508 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
jsgf855d93d2003-10-13 22:26:55 +00005509}
5510
sewardje6d5e722005-06-10 10:27:55 +00005511#undef PRE
5512#undef POST
sewardj2e93c502002-04-12 11:12:52 +00005513
sewardjde4a1d02002-03-22 01:27:54 +00005514/*--------------------------------------------------------------------*/
njnc1b01812005-06-17 22:19:06 +00005515/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00005516/*--------------------------------------------------------------------*/
sewardj45f4e7c2005-09-27 19:20:21 +00005517