Add core errors and use them to implement file descriptor tracker
[valgrind.git] / coregrind / m_syswrap / syswrap-generic.c
blobfa218ddbde3e5236ed50476e9853987e0a4027ea
1 /* -*- mode: C; c-basic-offset: 3; -*- */
3 /*--------------------------------------------------------------------*/
4 /*--- Wrappers for generic Unix system calls ---*/
5 /*--- syswrap-generic.c ---*/
6 /*--------------------------------------------------------------------*/
8 /*
9 This file is part of Valgrind, a dynamic binary instrumentation
10 framework.
12 Copyright (C) 2000-2017 Julian Seward
13 jseward@acm.org
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, see <http://www.gnu.org/licenses/>.
28 The GNU General Public License is contained in the file COPYING.
31 #if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_threadstate.h"
37 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_transtab.h" // VG_(discard_translations)
40 #include "pub_core_xarray.h"
41 #include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit)
42 #include "pub_core_debuglog.h"
43 #include "pub_core_errormgr.h" // For VG_(maybe_record_error)
44 #include "pub_core_gdbserver.h" // VG_(gdbserver)
45 #include "pub_core_libcbase.h"
46 #include "pub_core_libcassert.h"
47 #include "pub_core_libcfile.h"
48 #include "pub_core_libcprint.h"
49 #include "pub_core_libcproc.h"
50 #include "pub_core_libcsignal.h"
51 #include "pub_core_machine.h" // VG_(get_SP)
52 #include "pub_core_mallocfree.h"
53 #include "pub_core_options.h"
54 #include "pub_core_scheduler.h"
55 #include "pub_core_signals.h"
56 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
57 #include "pub_core_syscall.h"
58 #include "pub_core_syswrap.h"
59 #include "pub_core_tooliface.h"
60 #include "pub_core_ume.h"
61 #include "pub_core_stacks.h"
63 #include "priv_types_n_macros.h"
64 #include "priv_syswrap-generic.h"
66 #include "config.h"
68 static
69 HChar *getsockdetails(Int fd, UInt len, HChar *buf);
71 void ML_(guess_and_register_stack) (Addr sp, ThreadState* tst)
73 Bool debug = False;
74 NSegment const* seg;
76 /* We don't really know where the client stack is, because its
77 allocated by the client. The best we can do is look at the
78 memory mappings and try to derive some useful information. We
79 assume that sp starts near its highest possible value, and can
80 only go down to the start of the mmaped segment. */
81 seg = VG_(am_find_nsegment)(sp);
82 if (seg
83 && VG_(am_is_valid_for_client)(sp, 1, VKI_PROT_READ | VKI_PROT_WRITE)) {
84 tst->client_stack_highest_byte = (Addr)VG_PGROUNDUP(sp)-1;
85 tst->client_stack_szB = tst->client_stack_highest_byte - seg->start + 1;
87 tst->os_state.stk_id
88 = VG_(register_stack)(seg->start, tst->client_stack_highest_byte);
90 if (debug)
91 VG_(printf)("tid %u: guessed client stack range [%#lx-%#lx]"
92 " as stk_id %lu\n",
93 tst->tid, seg->start, tst->client_stack_highest_byte,
94 tst->os_state.stk_id);
95 } else {
96 VG_(message)(Vg_UserMsg,
97 "!? New thread %u starts with SP(%#lx) unmapped\n",
98 tst->tid, sp);
99 tst->client_stack_highest_byte = 0;
100 tst->client_stack_szB = 0;
104 /* Returns True iff address range is something the client can
105 plausibly mess with: all of it is either already belongs to the
106 client or is free or a reservation. */
108 Bool ML_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
109 const HChar *syscallname)
111 Bool ret;
113 if (size == 0)
114 return True;
116 ret = VG_(am_is_valid_for_client_or_free_or_resvn)
117 (start,size,VKI_PROT_NONE);
119 if (0)
120 VG_(printf)("%s: test=%#lx-%#lx ret=%d\n",
121 syscallname, start, start+size-1, (Int)ret);
123 if (!ret && syscallname != NULL) {
124 VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
125 "to modify addresses %#lx-%#lx\n",
126 syscallname, start, start+size-1);
127 if (VG_(clo_verbosity) > 1) {
128 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
132 return ret;
136 Bool ML_(client_signal_OK)(Int sigNo)
138 /* signal 0 is OK for kill */
139 Bool ret = sigNo >= 0 && sigNo <= VG_SIGVGRTUSERMAX;
141 //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret);
143 return ret;
147 /* Handy small function to help stop wrappers from segfaulting when
148 presented with bogus client addresses. Is not used for generating
149 user-visible errors. */
151 Bool ML_(safe_to_deref) ( const void *start, SizeT size )
153 return VG_(am_is_valid_for_client)( (Addr)start, size, VKI_PROT_READ );
157 /* ---------------------------------------------------------------------
158 Doing mmap, mremap
159 ------------------------------------------------------------------ */
161 /* AFAICT from kernel sources (mm/mprotect.c) and general experimentation,
162 munmap, mprotect (and mremap??) work at the page level. So addresses
163 and lengths must be adjusted for this. */
165 /* Mash around start and length so that the area exactly covers
166 an integral number of pages. If we don't do that, memcheck's
167 idea of addressible memory diverges from that of the
168 kernel's, which causes the leak detector to crash. */
169 static
170 void page_align_addr_and_len( Addr* a, SizeT* len)
172 Addr ra;
174 ra = VG_PGROUNDDN(*a);
175 *len = VG_PGROUNDUP(*a + *len) - ra;
176 *a = ra;
179 static void notify_core_of_mmap(Addr a, SizeT len, UInt prot,
180 UInt flags, Int fd, Off64T offset)
182 Bool d;
184 /* 'a' is the return value from a real kernel mmap, hence: */
185 vg_assert(VG_IS_PAGE_ALIGNED(a));
186 /* whereas len is whatever the syscall supplied. So: */
187 len = VG_PGROUNDUP(len);
189 d = VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset );
191 if (d)
192 VG_(discard_translations)( a, (ULong)len,
193 "notify_core_of_mmap" );
196 static void notify_tool_of_mmap(Addr a, SizeT len, UInt prot, ULong di_handle)
198 Bool rr, ww, xx;
200 /* 'a' is the return value from a real kernel mmap, hence: */
201 vg_assert(VG_IS_PAGE_ALIGNED(a));
202 /* whereas len is whatever the syscall supplied. So: */
203 len = VG_PGROUNDUP(len);
205 rr = toBool(prot & VKI_PROT_READ);
206 ww = toBool(prot & VKI_PROT_WRITE);
207 xx = toBool(prot & VKI_PROT_EXEC);
209 VG_TRACK( new_mem_mmap, a, len, rr, ww, xx, di_handle );
213 /* When a client mmap has been successfully done, this function must
214 be called. It notifies both aspacem and the tool of the new
215 mapping.
217 JRS 2008-Aug-14: But notice this is *very* obscure. The only place
218 it is called from is POST(sys_io_setup). In particular,
219 ML_(generic_PRE_sys_mmap), in m_syswrap, is the "normal case" handler for
220 client mmap. But it doesn't call this function; instead it does the
221 relevant notifications itself. Here, we just pass di_handle=0 to
222 notify_tool_of_mmap as we have no better information. But really this
223 function should be done away with; problem is I don't understand what
224 POST(sys_io_setup) does or how it works.
226 [However, this function is used lots for Darwin, because
227 ML_(generic_PRE_sys_mmap) cannot be used for Darwin.]
229 void
230 ML_(notify_core_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot,
231 UInt flags, Int fd, Off64T offset )
233 // XXX: unlike the other notify_core_and_tool* functions, this one doesn't
234 // do anything with debug info (ie. it doesn't call VG_(di_notify_mmap)).
235 // Should it? --njn
236 notify_core_of_mmap(a, len, prot, flags, fd, offset);
237 notify_tool_of_mmap(a, len, prot, 0/*di_handle*/);
240 void
241 ML_(notify_core_and_tool_of_munmap) ( Addr a, SizeT len )
243 Bool d;
245 page_align_addr_and_len(&a, &len);
246 d = VG_(am_notify_munmap)(a, len);
247 VG_TRACK( die_mem_munmap, a, len );
248 VG_(di_notify_munmap)( a, len );
249 if (d)
250 VG_(discard_translations)( a, (ULong)len,
251 "ML_(notify_core_and_tool_of_munmap)" );
254 void
255 ML_(notify_core_and_tool_of_mprotect) ( Addr a, SizeT len, Int prot )
257 Bool rr = toBool(prot & VKI_PROT_READ);
258 Bool ww = toBool(prot & VKI_PROT_WRITE);
259 Bool xx = toBool(prot & VKI_PROT_EXEC);
260 Bool d;
262 page_align_addr_and_len(&a, &len);
263 d = VG_(am_notify_mprotect)(a, len, prot);
264 VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
265 VG_(di_notify_mprotect)( a, len, prot );
266 if (d)
267 VG_(discard_translations)( a, (ULong)len,
268 "ML_(notify_core_and_tool_of_mprotect)" );
273 #if HAVE_MREMAP
274 /* Expand (or shrink) an existing mapping, potentially moving it at
275 the same time (controlled by the MREMAP_MAYMOVE flag). Nightmare.
277 static
278 SysRes do_mremap( Addr old_addr, SizeT old_len,
279 Addr new_addr, SizeT new_len,
280 UWord flags, ThreadId tid )
282 # define MIN_SIZET(_aa,_bb) (_aa) < (_bb) ? (_aa) : (_bb)
284 Bool ok, d;
285 NSegment const* old_seg;
286 Addr advised;
287 Bool f_fixed = toBool(flags & VKI_MREMAP_FIXED);
288 Bool f_maymove = toBool(flags & VKI_MREMAP_MAYMOVE);
290 if (0)
291 VG_(printf)("do_remap (old %#lx %lu) (new %#lx %lu) %s %s\n",
292 old_addr,old_len,new_addr,new_len,
293 flags & VKI_MREMAP_MAYMOVE ? "MAYMOVE" : "",
294 flags & VKI_MREMAP_FIXED ? "FIXED" : "");
295 if (0)
296 VG_(am_show_nsegments)(0, "do_remap: before");
298 if (flags & ~(VKI_MREMAP_FIXED | VKI_MREMAP_MAYMOVE))
299 goto eINVAL;
301 if (!VG_IS_PAGE_ALIGNED(old_addr))
302 goto eINVAL;
304 old_len = VG_PGROUNDUP(old_len);
305 new_len = VG_PGROUNDUP(new_len);
307 if (new_len == 0)
308 goto eINVAL;
310 /* kernel doesn't reject this, but we do. */
311 if (old_len == 0)
312 goto eINVAL;
314 /* reject wraparounds */
315 if (old_addr + old_len < old_addr)
316 goto eINVAL;
317 if (f_fixed == True && new_addr + new_len < new_len)
318 goto eINVAL;
320 /* kernel rejects all fixed, no-move requests (which are
321 meaningless). */
322 if (f_fixed == True && f_maymove == False)
323 goto eINVAL;
325 /* Stay away from non-client areas. */
326 if (!ML_(valid_client_addr)(old_addr, old_len, tid, "mremap(old_addr)"))
327 goto eINVAL;
329 /* In all remaining cases, if the old range does not fall within a
330 single segment, fail. */
331 old_seg = VG_(am_find_nsegment)( old_addr );
332 if (old_addr < old_seg->start || old_addr+old_len-1 > old_seg->end)
333 goto eINVAL;
334 if (old_seg->kind != SkAnonC && old_seg->kind != SkFileC
335 && old_seg->kind != SkShmC)
336 goto eINVAL;
338 vg_assert(old_len > 0);
339 vg_assert(new_len > 0);
340 vg_assert(VG_IS_PAGE_ALIGNED(old_len));
341 vg_assert(VG_IS_PAGE_ALIGNED(new_len));
342 vg_assert(VG_IS_PAGE_ALIGNED(old_addr));
344 /* There are 3 remaining cases:
346 * maymove == False
348 new space has to be at old address, so:
349 - shrink -> unmap end
350 - same size -> do nothing
351 - grow -> if can grow in-place, do so, else fail
353 * maymove == True, fixed == False
355 new space can be anywhere, so:
356 - shrink -> unmap end
357 - same size -> do nothing
358 - grow -> if can grow in-place, do so, else
359 move to anywhere large enough, else fail
361 * maymove == True, fixed == True
363 new space must be at new address, so:
365 - if new address is not page aligned, fail
366 - if new address range overlaps old one, fail
367 - if new address range cannot be allocated, fail
368 - else move to new address range with new size
369 - else fail
372 if (f_maymove == False) {
373 /* new space has to be at old address */
374 if (new_len < old_len)
375 goto shrink_in_place;
376 if (new_len > old_len)
377 goto grow_in_place_or_fail;
378 goto same_in_place;
381 if (f_maymove == True && f_fixed == False) {
382 /* new space can be anywhere */
383 if (new_len < old_len)
384 goto shrink_in_place;
385 if (new_len > old_len)
386 goto grow_in_place_or_move_anywhere_or_fail;
387 goto same_in_place;
390 if (f_maymove == True && f_fixed == True) {
391 /* new space can only be at the new address */
392 if (!VG_IS_PAGE_ALIGNED(new_addr))
393 goto eINVAL;
394 if (new_addr+new_len-1 < old_addr || new_addr > old_addr+old_len-1) {
395 /* no overlap */
396 } else {
397 goto eINVAL;
399 if (new_addr == 0)
400 goto eINVAL;
401 /* VG_(am_get_advisory_client_simple) interprets zero to mean
402 non-fixed, which is not what we want */
403 advised = VG_(am_get_advisory_client_simple)(new_addr, new_len, &ok);
404 if (!ok || advised != new_addr)
405 goto eNOMEM;
406 ok = VG_(am_relocate_nooverlap_client)
407 ( &d, old_addr, old_len, new_addr, new_len );
408 if (ok) {
409 VG_TRACK( copy_mem_remap, old_addr, new_addr,
410 MIN_SIZET(old_len,new_len) );
411 if (new_len > old_len)
412 VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len,
413 old_seg->hasR, old_seg->hasW, old_seg->hasX,
414 0/*di_handle*/ );
415 VG_TRACK(die_mem_munmap, old_addr, old_len);
416 if (d) {
417 VG_(discard_translations)( old_addr, old_len, "do_remap(1)" );
418 VG_(discard_translations)( new_addr, new_len, "do_remap(2)" );
420 return VG_(mk_SysRes_Success)( new_addr );
422 goto eNOMEM;
425 /* end of the 3 cases */
426 /*NOTREACHED*/ vg_assert(0);
428 grow_in_place_or_move_anywhere_or_fail:
430 /* try growing it in-place */
431 Addr needA = old_addr + old_len;
432 SSizeT needL = new_len - old_len;
434 vg_assert(needL > 0);
435 vg_assert(needA > 0);
437 advised = VG_(am_get_advisory_client_simple)( needA, needL, &ok );
438 if (ok) {
439 /* Fixes bug #129866. */
440 ok = VG_(am_covered_by_single_free_segment) ( needA, needL );
442 if (ok && advised == needA) {
443 const NSegment *new_seg = VG_(am_extend_map_client)( old_addr, needL );
444 if (new_seg) {
445 VG_TRACK( new_mem_mmap, needA, needL,
446 new_seg->hasR,
447 new_seg->hasW, new_seg->hasX,
448 0/*di_handle*/ );
449 return VG_(mk_SysRes_Success)( old_addr );
453 /* that failed. Look elsewhere. */
454 advised = VG_(am_get_advisory_client_simple)( 0, new_len, &ok );
455 if (ok) {
456 Bool oldR = old_seg->hasR;
457 Bool oldW = old_seg->hasW;
458 Bool oldX = old_seg->hasX;
459 /* assert new area does not overlap old */
460 vg_assert(advised+new_len-1 < old_addr
461 || advised > old_addr+old_len-1);
462 ok = VG_(am_relocate_nooverlap_client)
463 ( &d, old_addr, old_len, advised, new_len );
464 if (ok) {
465 VG_TRACK( copy_mem_remap, old_addr, advised,
466 MIN_SIZET(old_len,new_len) );
467 if (new_len > old_len)
468 VG_TRACK( new_mem_mmap, advised+old_len, new_len-old_len,
469 oldR, oldW, oldX, 0/*di_handle*/ );
470 VG_TRACK(die_mem_munmap, old_addr, old_len);
471 if (d) {
472 VG_(discard_translations)( old_addr, old_len, "do_remap(4)" );
473 VG_(discard_translations)( advised, new_len, "do_remap(5)" );
475 return VG_(mk_SysRes_Success)( advised );
478 goto eNOMEM;
480 /*NOTREACHED*/ vg_assert(0);
482 grow_in_place_or_fail:
484 Addr needA = old_addr + old_len;
485 SizeT needL = new_len - old_len;
487 vg_assert(needA > 0);
489 advised = VG_(am_get_advisory_client_simple)( needA, needL, &ok );
490 if (ok) {
491 /* Fixes bug #129866. */
492 ok = VG_(am_covered_by_single_free_segment) ( needA, needL );
494 if (!ok || advised != needA)
495 goto eNOMEM;
496 const NSegment *new_seg = VG_(am_extend_map_client)( old_addr, needL );
497 if (!new_seg)
498 goto eNOMEM;
499 VG_TRACK( new_mem_mmap, needA, needL,
500 new_seg->hasR, new_seg->hasW, new_seg->hasX,
501 0/*di_handle*/ );
503 return VG_(mk_SysRes_Success)( old_addr );
505 /*NOTREACHED*/ vg_assert(0);
507 shrink_in_place:
509 SysRes sres = VG_(am_munmap_client)( &d, old_addr+new_len, old_len-new_len );
510 if (sr_isError(sres))
511 return sres;
512 VG_TRACK( die_mem_munmap, old_addr+new_len, old_len-new_len );
513 if (d)
514 VG_(discard_translations)( old_addr+new_len, old_len-new_len,
515 "do_remap(7)" );
516 return VG_(mk_SysRes_Success)( old_addr );
518 /*NOTREACHED*/ vg_assert(0);
520 same_in_place:
521 return VG_(mk_SysRes_Success)( old_addr );
522 /*NOTREACHED*/ vg_assert(0);
524 eINVAL:
525 return VG_(mk_SysRes_Error)( VKI_EINVAL );
526 eNOMEM:
527 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
529 # undef MIN_SIZET
531 #endif /* HAVE_MREMAP */
534 /* ---------------------------------------------------------------------
535 File-descriptor tracking
536 ------------------------------------------------------------------ */
538 /* One of these is allocated for each open file descriptor. */
539 typedef struct OpenFd
541 Int fd; /* The file descriptor */
542 HChar *pathname; /* NULL if not a regular file or unknown */
543 ExeContext *where; /* NULL if inherited from parent */
544 ExeContext *where_closed; /* record the last close of fd */
545 Bool fd_closed;
546 struct OpenFd *next, *prev;
547 } OpenFd;
549 /* List of allocated file descriptors. */
550 static OpenFd *allocated_fds = NULL;
552 /* Count of open file descriptors. */
553 static Int fd_count = 0;
555 /* Close_range caller might want to close very wide range of file descriptors,
556 up to 0U. We want to avoid iterating through such a range in a normall
557 close_range, just up to any open file descriptor. Also, unlike
558 record_fd_close_range, we assume the user might deliberately double closes
559 any file descriptors in the range, so don't warn about double close here. */
560 void ML_(record_fd_close_range)(ThreadId tid, Int from_fd)
562 OpenFd *i = allocated_fds;
564 if (from_fd >= VG_(fd_hard_limit))
565 return; /* Valgrind internal */
567 while(i) {
568 // Assume the user doesn't want a warning if this came from
569 // close_range. Just record the file descriptors not yet closed here.
570 if (i->fd >= from_fd && !i->fd_closed
571 && i->fd != VG_(log_output_sink).fd
572 && i->fd != VG_(xml_output_sink).fd) {
573 i->fd_closed = True;
574 i->where_closed = ((tid == -1)
575 ? NULL
576 : VG_(record_ExeContext)(tid,
577 0/*first_ip_delta*/));
578 fd_count--;
580 i = i->next;
584 struct BadCloseExtra {
585 Int fd; /* The file descriptor */
586 HChar *pathname; /* NULL if not a regular file or unknown */
587 ExeContext *where_closed; /* record the last close of fd */
588 ExeContext *where_opened; /* recordwhere the fd was opened */
591 struct NotClosedExtra {
592 Int fd;
593 HChar description[256];
596 /* Note the fact that a file descriptor was just closed. */
597 void ML_(record_fd_close)(ThreadId tid, Int fd)
599 OpenFd *i = allocated_fds;
601 if (fd >= VG_(fd_hard_limit))
602 return; /* Valgrind internal */
604 while(i) {
605 if (i->fd == fd) {
606 if (i->fd_closed) {
607 struct BadCloseExtra bce;
608 bce.fd = i->fd;
609 bce.pathname = i->pathname;
610 bce.where_opened = i->where;
611 bce.where_closed = i->where_closed;
612 VG_(maybe_record_error)(tid, FdBadClose, 0,
613 "file descriptor already closed", &bce);
614 } else {
615 i->fd_closed = True;
616 i->where_closed = ((tid == -1)
617 ? NULL
618 : VG_(record_ExeContext)(tid,
619 0/*first_ip_delta*/));
620 /* Record path/socket name, etc. In case we want to print it later,
621 for example for double close. Note that record_fd_close is
622 actually called from the PRE syscall handler, so the file
623 description is about to be closed, but hasn't yet at this
624 point. */
625 if (!i->pathname) {
626 Int val;
627 Int len = sizeof(val);
628 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE,
629 &val, &len) == -1) {
630 HChar *pathname = VG_(malloc)("vg.record_fd_close.fd", 30);
631 VG_(snprintf)(pathname, 30, "file descriptor %d", i->fd);
632 i->pathname = pathname;
633 } else {
634 HChar *name = VG_(malloc)("vg.record_fd_close.sock", 256);
635 i->pathname = getsockdetails(i->fd, 256, name);
638 fd_count--;
640 break;
642 i = i->next;
646 /* Note the fact that a file descriptor was just opened. If the
647 tid is -1, this indicates an inherited fd. If the pathname is NULL,
648 this either indicates a non-standard file (i.e. a pipe or socket or
649 some such thing) or that we don't know the filename. If the fd is
650 already open, then we're probably doing a dup2() to an existing fd,
651 so just overwrite the existing one. */
652 void ML_(record_fd_open_with_given_name)(ThreadId tid, Int fd,
653 const HChar *pathname)
655 OpenFd *i;
657 if (fd >= VG_(fd_hard_limit))
658 return; /* Valgrind internal */
660 /* Check to see if this fd is already open (or closed, we will just
661 override it. */
662 i = allocated_fds;
663 while (i) {
664 if (i->fd == fd) {
665 if (i->pathname) {
666 VG_(free)(i->pathname);
667 i->pathname = NULL;
669 if (i->fd_closed) /* now we will open it. */
670 fd_count++;
671 break;
673 i = i->next;
676 /* Not already one: allocate an OpenFd */
677 if (i == NULL) {
678 i = VG_(malloc)("syswrap.rfdowgn.1", sizeof(OpenFd));
680 i->prev = NULL;
681 i->next = allocated_fds;
682 if(allocated_fds) allocated_fds->prev = i;
683 allocated_fds = i;
684 fd_count++;
687 i->fd = fd;
688 i->pathname = VG_(strdup)("syswrap.rfdowgn.2", pathname);
689 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
690 i->fd_closed = False;
691 i->where_closed = NULL;
694 // Record opening of an fd, and find its name.
695 void ML_(record_fd_open_named)(ThreadId tid, Int fd)
697 const HChar* buf;
698 const HChar* name;
699 if (VG_(resolve_filename)(fd, &buf))
700 name = buf;
701 else
702 name = NULL;
704 ML_(record_fd_open_with_given_name)(tid, fd, name);
707 // Record opening of a nameless fd.
708 void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
710 ML_(record_fd_open_with_given_name)(tid, fd, NULL);
713 // Return if a given file descriptor is already recorded.
714 Bool ML_(fd_recorded)(Int fd)
716 OpenFd *i = allocated_fds;
717 while (i) {
718 if (i->fd == fd) {
719 if (i->fd_closed)
720 return False;
721 else
722 return True;
724 i = i->next;
726 return False;
729 /* Returned string must not be modified nor free'd. */
730 const HChar *ML_(find_fd_recorded_by_fd)(Int fd)
732 OpenFd *i = allocated_fds;
734 while (i) {
735 if (i->fd == fd) {
736 if (i->fd_closed)
737 return NULL;
738 else
739 return i->pathname;
741 i = i->next;
744 return NULL;
747 static
748 HChar *unix_to_name(struct vki_sockaddr_un *sa, UInt len, HChar *name)
750 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
751 VG_(sprintf)(name, "<unknown>");
752 } else {
753 VG_(sprintf)(name, "%s", sa->sun_path);
756 return name;
759 static
760 HChar *inet_to_name(struct vki_sockaddr_in *sa, UInt len, HChar *name)
762 if (sa == NULL || len == 0) {
763 VG_(sprintf)(name, "<unknown>");
764 } else if (sa->sin_port == 0) {
765 VG_(sprintf)(name, "<unbound>");
766 } else {
767 UInt addr = VG_(ntohl)(sa->sin_addr.s_addr);
768 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
769 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
770 (addr>>8) & 0xFF, addr & 0xFF,
771 VG_(ntohs)(sa->sin_port));
774 return name;
777 static
778 void inet6_format(HChar *s, const UChar ip[16])
780 static const unsigned char V4mappedprefix[12] = {0,0,0,0,0,0,0,0,0,0,0xff,0xff};
782 if (!VG_(memcmp)(ip, V4mappedprefix, 12)) {
783 const struct vki_in_addr *sin_addr =
784 (const struct vki_in_addr *)(ip + 12);
785 UInt addr = VG_(ntohl)(sin_addr->s_addr);
787 VG_(sprintf)(s, "::ffff:%u.%u.%u.%u",
788 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
789 (addr>>8) & 0xFF, addr & 0xFF);
790 } else {
791 Bool compressing = False;
792 Bool compressed = False;
793 Int len = 0;
794 Int i;
796 for (i = 0; i < 16; i += 2) {
797 UInt word = ((UInt)ip[i] << 8) | (UInt)ip[i+1];
798 if (word == 0 && !compressed) {
799 compressing = True;
800 } else {
801 if (compressing) {
802 compressing = False;
803 compressed = True;
804 s[len++] = ':';
806 if (i > 0) {
807 s[len++] = ':';
809 len += VG_(sprintf)(s + len, "%x", word);
813 if (compressing) {
814 s[len++] = ':';
815 s[len++] = ':';
818 s[len++] = 0;
821 return;
824 static
825 HChar *inet6_to_name(struct vki_sockaddr_in6 *sa, UInt len, HChar *name)
827 if (sa == NULL || len == 0) {
828 VG_(sprintf)(name, "<unknown>");
829 } else if (sa->sin6_port == 0) {
830 VG_(sprintf)(name, "<unbound>");
831 } else {
832 HChar addr[100]; // large enough
833 inet6_format(addr, (void *)&(sa->sin6_addr));
834 VG_(sprintf)(name, "[%s]:%u", addr, VG_(ntohs)(sa->sin6_port));
837 return name;
841 * Try get some details about a socket.
842 * Returns the given BUF with max length LEN.
844 static
845 HChar *getsockdetails(Int fd, UInt len, HChar *buf)
847 union u {
848 struct vki_sockaddr a;
849 struct vki_sockaddr_in in;
850 struct vki_sockaddr_in6 in6;
851 struct vki_sockaddr_un un;
852 } laddr;
853 Int llen;
855 llen = sizeof(laddr);
856 VG_(memset)(&laddr, 0, llen);
858 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
859 switch(laddr.a.sa_family) {
860 case VKI_AF_INET: {
861 HChar lname[32]; // large enough
862 HChar pname[32]; // large enough
863 struct vki_sockaddr_in paddr;
864 Int plen = sizeof(struct vki_sockaddr_in);
866 if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
867 VG_(snprintf)(buf, len, "AF_INET socket %d: %s <-> %s", fd,
868 inet_to_name(&(laddr.in), llen, lname),
869 inet_to_name(&paddr, plen, pname));
870 return buf;
871 } else {
872 VG_(snprintf)(buf, len, "AF_INET socket %d: %s <-> <unbound>",
873 fd, inet_to_name(&(laddr.in), llen, lname));
874 return buf;
877 case VKI_AF_INET6: {
878 HChar lname[128]; // large enough
879 HChar pname[128]; // large enough
880 struct vki_sockaddr_in6 paddr;
881 Int plen = sizeof(struct vki_sockaddr_in6);
883 if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
884 VG_(snprintf)(buf, len, "AF_INET6 socket %d: %s <-> %s", fd,
885 inet6_to_name(&(laddr.in6), llen, lname),
886 inet6_to_name(&paddr, plen, pname));
887 return buf;
888 } else {
889 VG_(snprintf)(buf, len, "AF_INET6 socket %d: %s <-> <unbound>",
890 fd, inet6_to_name(&(laddr.in6), llen, lname));
891 return buf;
894 case VKI_AF_UNIX: {
895 static char lname[256];
896 VG_(snprintf)(buf, len, "AF_UNIX socket %d: %s", fd,
897 unix_to_name(&(laddr.un), llen, lname));
898 return buf;
900 default:
901 VG_(snprintf)(buf, len, "pf-%d socket %d",
902 laddr.a.sa_family, fd);
903 return buf;
907 VG_(snprintf)(buf, len, "socket %d", fd);
908 return buf;
912 /* Dump out a summary, and a more detailed list, of open file descriptors. */
913 void VG_(show_open_fds) (const HChar* when)
915 OpenFd *i;
916 int non_std = 0;
918 for (i = allocated_fds; i; i = i->next) {
919 if (i->fd > 2 && i->fd_closed != True)
920 non_std++;
923 /* If we are running quiet and there are either no open file descriptors
924 or not tracking all fds, then don't report anything. */
925 if ((fd_count == 0
926 || ((non_std == 0) && (VG_(clo_track_fds) < 2)))
927 && (VG_(clo_verbosity) == 0))
928 return;
930 if (!VG_(clo_xml)) {
931 VG_(umsg)("FILE DESCRIPTORS: %d open (%d std) %s.\n",
932 fd_count, fd_count - non_std, when);
935 for (i = allocated_fds; i; i = i->next) {
936 if (i->fd_closed)
937 continue;
939 if (i->fd <= 2 && VG_(clo_track_fds) < 2)
940 continue;
942 struct NotClosedExtra nce;
943 if (i->pathname) {
944 VG_(snprintf) (nce.description, 256, "file descriptor %d: %s",
945 i->fd, i->pathname);
946 } else {
947 Int val;
948 Int len = sizeof(val);
950 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len)
951 == -1) {
952 VG_(sprintf)(nce.description, "file descriptor %d:", i->fd);
953 } else {
954 getsockdetails(i->fd, 256, nce.description);
958 nce.fd = i->fd;
959 VG_(unique_error) (1 /* Fake ThreadId */,
960 FdNotClosed,
961 0, /* Addr */
962 "Still Open file descriptor",
963 &nce, /* extra */
964 i->where,
965 True, /* print_error */
966 False, /* allow_GDB_attach */
967 True /* count_error */);
971 VG_(message)(Vg_UserMsg, "\n");
974 /* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't
975 have /proc support compiled in, or a non-Linux kernel), then we need to
976 find out what file descriptors we inherited from our parent process the
977 hard way - by checking each fd in turn. */
978 static
979 void init_preopened_fds_without_proc_self_fd(void)
981 struct vki_rlimit lim;
982 UInt count;
983 Int i;
985 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
986 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
987 an arbitrarily high number. 1024 happens to be the limit in
988 the 2.4 Linux kernels. */
989 count = 1024;
990 } else {
991 count = lim.rlim_cur;
994 for (i = 0; i < count; i++)
995 if (VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
996 ML_(record_fd_open_named)(-1, i);
999 /* Initialize the list of open file descriptors with the file descriptors
1000 we inherited from out parent process. */
1002 void VG_(init_preopened_fds)(void)
1004 // DDD: should probably use HAVE_PROC here or similar, instead.
1005 #if defined(VGO_linux)
1006 Int ret;
1007 struct vki_dirent64 d;
1008 SysRes f;
1010 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
1011 if (sr_isError(f)) {
1012 init_preopened_fds_without_proc_self_fd();
1013 return;
1016 while ((ret = VG_(getdents64)(sr_Res(f), &d, sizeof(d))) != 0) {
1017 if (ret == -1)
1018 goto out;
1020 if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
1021 HChar* s;
1022 Int fno = VG_(strtoll10)(d.d_name, &s);
1023 if (*s == '\0') {
1024 if (fno != sr_Res(f))
1025 if (VG_(clo_track_fds))
1026 ML_(record_fd_open_named)(-1, fno);
1027 } else {
1028 VG_(message)(Vg_DebugMsg,
1029 "Warning: invalid file name in /proc/self/fd: %s\n",
1030 d.d_name);
1034 VG_(lseek)(sr_Res(f), d.d_off, VKI_SEEK_SET);
1037 out:
1038 VG_(close)(sr_Res(f));
1040 #elif defined(VGO_darwin) || defined(VGO_freebsd)
1041 init_preopened_fds_without_proc_self_fd();
1043 #elif defined(VGO_solaris)
1044 Int ret;
1045 Char buf[VKI_MAXGETDENTS_SIZE];
1046 SysRes f;
1048 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
1049 if (sr_isError(f)) {
1050 init_preopened_fds_without_proc_self_fd();
1051 return;
1054 while ((ret = VG_(getdents64)(sr_Res(f), (struct vki_dirent64 *) buf,
1055 sizeof(buf))) > 0) {
1056 Int i = 0;
1057 while (i < ret) {
1058 /* Proceed one entry. */
1059 struct vki_dirent64 *d = (struct vki_dirent64 *) (buf + i);
1060 if (VG_(strcmp)(d->d_name, ".") && VG_(strcmp)(d->d_name, "..")) {
1061 HChar *s;
1062 Int fno = VG_(strtoll10)(d->d_name, &s);
1063 if (*s == '\0') {
1064 if (fno != sr_Res(f))
1065 if (VG_(clo_track_fds))
1066 ML_(record_fd_open_named)(-1, fno);
1067 } else {
1068 VG_(message)(Vg_DebugMsg,
1069 "Warning: invalid file name in /proc/self/fd: %s\n",
1070 d->d_name);
1074 /* Move on the next entry. */
1075 i += d->d_reclen;
1079 VG_(close)(sr_Res(f));
1081 #else
1082 # error Unknown OS
1083 #endif
1086 Bool fd_eq_Error (VgRes res, const Error *e1, const Error *e2)
1088 // XXX should we compare the fds?
1089 return False;
1092 void fd_before_pp_Error (const Error *err)
1094 // Nothing to do here
1097 void fd_pp_Error (const Error *err)
1099 const Bool xml = VG_(clo_xml);
1100 const HChar* whatpre = VG_(clo_xml) ? " <what>" : "";
1101 const HChar* whatpost = VG_(clo_xml) ? "</what>" : "";
1102 const HChar* auxpre = VG_(clo_xml) ? " <auxwhat>" : " ";
1103 const HChar* auxpost = VG_(clo_xml) ? "</auxwhat>" : "";
1104 ExeContext *where = VG_(get_error_where)(err);
1105 if (VG_(get_error_kind)(err) == FdBadClose) {
1106 if (xml) VG_(emit)(" <kind>FdBadClose</kind>\n");
1107 struct BadCloseExtra *bce = (struct BadCloseExtra *)
1108 VG_(get_error_extra)(err);
1109 VG_(emit)("%sFile descriptor %d: %s is already closed%s\n",
1110 whatpre, bce->fd, bce->pathname, whatpost);
1111 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
1112 VG_(emit)("%sPreviously closed%s\n", auxpre, auxpost);
1113 VG_(pp_ExeContext)(bce->where_closed);
1114 VG_(emit)("%sOriginally opened%s\n", auxpre, auxpost);
1115 VG_(pp_ExeContext)(bce->where_opened);
1116 } else if (VG_(get_error_kind)(err) == FdNotClosed) {
1117 if (xml) VG_(emit)(" <kind>FdNotClosed</kind>\n");
1118 struct NotClosedExtra *nce = (struct NotClosedExtra *)
1119 VG_(get_error_extra)(err);
1120 VG_(emit)("%sOpen %s%s\n", whatpre, nce->description, whatpost);
1121 if (where != NULL) {
1122 VG_(pp_ExeContext)(where);
1123 if (!xml) VG_(message)(Vg_UserMsg, "\n");
1124 } else if (!xml) {
1125 VG_(message)(Vg_UserMsg, " <inherited from parent>\n");
1126 VG_(message)(Vg_UserMsg, "\n");
1128 } else {
1129 vg_assert2 (False, "Unknown error kind: %d",
1130 VG_(get_error_kind)(err));
1134 /* Called to see if there is any extra state to be saved with this
1135 error. Must return the size of the extra struct. */
1136 UInt fd_update_extra (const Error *err)
1138 if (VG_(get_error_kind)(err) == FdBadClose)
1139 return sizeof (struct BadCloseExtra);
1140 else if (VG_(get_error_kind)(err) == FdNotClosed)
1141 return sizeof (struct NotClosedExtra);
1142 else {
1143 vg_assert2 (False, "Unknown error kind: %d",
1144 VG_(get_error_kind)(err));
1148 static
1149 void pre_mem_read_sendmsg ( ThreadId tid, Bool read,
1150 const HChar *msg, Addr base, SizeT size )
1152 HChar outmsg[VG_(strlen)(msg) + 10]; // large enough
1153 VG_(sprintf)(outmsg, "sendmsg%s", msg);
1154 PRE_MEM_READ( outmsg, base, size );
1157 static
1158 void pre_mem_write_recvmsg ( ThreadId tid, Bool read,
1159 const HChar *msg, Addr base, SizeT size )
1161 HChar outmsg[VG_(strlen)(msg) + 10]; // large enough
1162 VG_(sprintf)(outmsg, "recvmsg%s", msg);
1163 if ( read )
1164 PRE_MEM_READ( outmsg, base, size );
1165 else
1166 PRE_MEM_WRITE( outmsg, base, size );
1169 static
1170 void post_mem_write_recvmsg ( ThreadId tid, Bool read,
1171 const HChar *fieldName, Addr base, SizeT size )
1173 if ( !read )
1174 POST_MEM_WRITE( base, size );
1177 static
1178 void msghdr_foreachfield (
1179 ThreadId tid,
1180 const HChar *name,
1181 struct vki_msghdr *msg,
1182 UInt length,
1183 void (*foreach_func)( ThreadId, Bool, const HChar *, Addr, SizeT ),
1184 Bool rekv /* "recv" apparently shadows some header decl on OSX108 */
1187 HChar fieldName[VG_(strlen)(name) + 32]; // large enough.
1188 Addr a;
1189 SizeT s;
1191 if ( !msg )
1192 return;
1194 VG_(sprintf) ( fieldName, "(%s)", name );
1196 /* FIELDPAIR helps the compiler do one call to foreach_func
1197 for consecutive (no holes) fields. */
1198 #define FIELDPAIR(f1,f2) \
1199 if (offsetof(struct vki_msghdr, f1) + sizeof(msg->f1) \
1200 == offsetof(struct vki_msghdr, f2)) \
1201 s += sizeof(msg->f2); \
1202 else { \
1203 foreach_func (tid, True, fieldName, a, s); \
1204 a = (Addr)&msg->f2; \
1205 s = sizeof(msg->f2); \
1208 a = (Addr)&msg->msg_name;
1209 s = sizeof(msg->msg_name);
1210 FIELDPAIR(msg_name, msg_namelen);
1211 FIELDPAIR(msg_namelen, msg_iov);
1212 FIELDPAIR(msg_iov, msg_iovlen);
1213 FIELDPAIR(msg_iovlen, msg_control);
1214 FIELDPAIR(msg_control, msg_controllen);
1215 foreach_func ( tid, True, fieldName, a, s);
1216 #undef FIELDPAIR
1218 /* msg_flags is completely ignored for send_mesg, recv_mesg doesn't read
1219 the field, but does write to it. */
1220 if ( rekv )
1221 foreach_func ( tid, False, fieldName, (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) );
1223 if ( ML_(safe_to_deref)(&msg->msg_name, sizeof (void *))
1224 && msg->msg_name ) {
1225 VG_(sprintf) ( fieldName, "(%s.msg_name)", name );
1226 foreach_func ( tid, False, fieldName,
1227 (Addr)msg->msg_name, msg->msg_namelen );
1230 if ( ML_(safe_to_deref)(&msg->msg_iov, sizeof (void *))
1231 && msg->msg_iov ) {
1232 struct vki_iovec *iov = msg->msg_iov;
1233 UInt i;
1235 if (ML_(safe_to_deref)(&msg->msg_iovlen, sizeof (UInt))) {
1236 VG_(sprintf) ( fieldName, "(%s.msg_iov)", name );
1237 foreach_func ( tid, True, fieldName, (Addr)iov,
1238 msg->msg_iovlen * sizeof( struct vki_iovec ) );
1240 for ( i = 0; i < msg->msg_iovlen && length > 0; ++i, ++iov ) {
1241 if (ML_(safe_to_deref)(&iov->iov_len, sizeof (UInt))) {
1242 UInt iov_len = iov->iov_len <= length ? iov->iov_len : length;
1243 VG_(sprintf) ( fieldName, "(%s.msg_iov[%u])", name, i );
1244 foreach_func ( tid, False, fieldName,
1245 (Addr)iov->iov_base, iov_len );
1246 length = length - iov_len;
1252 if ( ML_(safe_to_deref) (&msg->msg_control, sizeof (void *))
1253 && msg->msg_control ) {
1254 VG_(sprintf) ( fieldName, "(%s.msg_control)", name );
1255 foreach_func ( tid, False, fieldName,
1256 (Addr)msg->msg_control, msg->msg_controllen );
1261 static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
1263 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
1265 while (cm) {
1266 if (cm->cmsg_level == VKI_SOL_SOCKET
1267 && cm->cmsg_type == VKI_SCM_RIGHTS ) {
1268 Int *fds = (Int *) VKI_CMSG_DATA(cm);
1269 Int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
1270 / sizeof(int);
1271 Int i;
1273 for (i = 0; i < fdc; i++)
1274 if(VG_(clo_track_fds))
1275 // XXX: must we check the range on these fds with
1276 // ML_(fd_allowed)()?
1277 ML_(record_fd_open_named)(tid, fds[i]);
1280 cm = VKI_CMSG_NXTHDR(msg, cm);
1284 /* GrP kernel ignores sa_len (at least on Darwin); this checks the rest */
1285 void ML_(pre_mem_read_sockaddr) ( ThreadId tid,
1286 const HChar *description,
1287 struct vki_sockaddr *sa, UInt salen )
1289 HChar outmsg[VG_(strlen)( description ) + 30]; // large enough
1290 struct vki_sockaddr_un* saun = (struct vki_sockaddr_un *)sa;
1291 struct vki_sockaddr_in* sin = (struct vki_sockaddr_in *)sa;
1292 struct vki_sockaddr_in6* sin6 = (struct vki_sockaddr_in6 *)sa;
1293 # ifdef VKI_AF_BLUETOOTH
1294 struct vki_sockaddr_rc* rc = (struct vki_sockaddr_rc *)sa;
1295 # endif
1296 # ifdef VKI_AF_NETLINK
1297 struct vki_sockaddr_nl* nl = (struct vki_sockaddr_nl *)sa;
1298 # endif
1300 /* NULL/zero-length sockaddrs are legal */
1301 if ( sa == NULL || salen == 0 ) return;
1303 VG_(sprintf) ( outmsg, description, "sa_family" );
1304 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
1305 #if defined(VGO_freebsd)
1306 VG_(sprintf) ( outmsg, description, "sa_len" );
1307 PRE_MEM_READ( outmsg, (Addr) &sa->sa_len, sizeof(char));
1308 #endif
1310 /* Don't do any extra checking if we cannot determine the sa_family. */
1311 if (! ML_(safe_to_deref) (&sa->sa_family, sizeof(vki_sa_family_t)))
1312 return;
1314 switch (sa->sa_family) {
1316 case VKI_AF_UNIX:
1317 if (ML_(safe_to_deref) (&saun->sun_path, sizeof (Addr))) {
1318 VG_(sprintf) ( outmsg, description, "sun_path" );
1319 PRE_MEM_RASCIIZ( outmsg, (Addr) saun->sun_path );
1320 // GrP fixme max of sun_len-2? what about nul char?
1322 break;
1324 case VKI_AF_INET:
1325 VG_(sprintf) ( outmsg, description, "sin_port" );
1326 PRE_MEM_READ( outmsg, (Addr) &sin->sin_port, sizeof (sin->sin_port) );
1327 VG_(sprintf) ( outmsg, description, "sin_addr" );
1328 PRE_MEM_READ( outmsg, (Addr) &sin->sin_addr, sizeof (sin->sin_addr) );
1329 break;
1331 case VKI_AF_INET6:
1332 VG_(sprintf) ( outmsg, description, "sin6_port" );
1333 PRE_MEM_READ( outmsg,
1334 (Addr) &sin6->sin6_port, sizeof (sin6->sin6_port) );
1335 VG_(sprintf) ( outmsg, description, "sin6_flowinfo" );
1336 PRE_MEM_READ( outmsg,
1337 (Addr) &sin6->sin6_flowinfo, sizeof (sin6->sin6_flowinfo) );
1338 VG_(sprintf) ( outmsg, description, "sin6_addr" );
1339 PRE_MEM_READ( outmsg,
1340 (Addr) &sin6->sin6_addr, sizeof (sin6->sin6_addr) );
1341 VG_(sprintf) ( outmsg, description, "sin6_scope_id" );
1342 PRE_MEM_READ( outmsg,
1343 (Addr) &sin6->sin6_scope_id, sizeof (sin6->sin6_scope_id) );
1344 break;
1346 # ifdef VKI_AF_BLUETOOTH
1347 case VKI_AF_BLUETOOTH:
1348 VG_(sprintf) ( outmsg, description, "rc_bdaddr" );
1349 PRE_MEM_READ( outmsg, (Addr) &rc->rc_bdaddr, sizeof (rc->rc_bdaddr) );
1350 VG_(sprintf) ( outmsg, description, "rc_channel" );
1351 PRE_MEM_READ( outmsg, (Addr) &rc->rc_channel, sizeof (rc->rc_channel) );
1352 break;
1353 # endif
1355 # ifdef VKI_AF_NETLINK
1356 case VKI_AF_NETLINK:
1357 VG_(sprintf)(outmsg, description, "nl_pid");
1358 PRE_MEM_READ(outmsg, (Addr)&nl->nl_pid, sizeof(nl->nl_pid));
1359 VG_(sprintf)(outmsg, description, "nl_groups");
1360 PRE_MEM_READ(outmsg, (Addr)&nl->nl_groups, sizeof(nl->nl_groups));
1361 break;
1362 # endif
1364 # ifdef VKI_AF_UNSPEC
1365 case VKI_AF_UNSPEC:
1366 break;
1367 # endif
1369 default:
1370 /* No specific information about this address family.
1371 Let's just check the full data following the family.
1372 Note that this can give false positive if this (unknown)
1373 struct sockaddr_???? has padding bytes between its elements. */
1374 VG_(sprintf) ( outmsg, description, "sa_data" );
1375 PRE_MEM_READ( outmsg, (Addr)&sa->sa_family + sizeof(sa->sa_family),
1376 salen - sizeof(sa->sa_family));
1377 break;
1381 /* Dereference a pointer to a UInt. */
1382 static UInt deref_UInt ( ThreadId tid, Addr a, const HChar* s )
1384 UInt* a_p = (UInt*)a;
1385 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
1386 if (a_p == NULL || ! ML_(safe_to_deref) (a_p, sizeof(UInt)))
1387 return 0;
1388 else
1389 return *a_p;
1392 void ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p,
1393 const HChar* buf_s, const HChar* buflen_s )
1395 if (VG_(tdict).track_pre_mem_write) {
1396 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
1397 if (buflen_in > 0) {
1398 VG_(tdict).track_pre_mem_write(
1399 Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
1404 void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res,
1405 Addr buf_p, Addr buflen_p, const HChar* s )
1407 if (!sr_isError(res) && VG_(tdict).track_post_mem_write) {
1408 UInt buflen_out = deref_UInt( tid, buflen_p, s);
1409 if (buflen_out > 0 && buf_p != (Addr)NULL) {
1410 VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
1415 /* ---------------------------------------------------------------------
1416 Data seg end, for brk()
1417 ------------------------------------------------------------------ */
1419 /* +--------+------------+
1420 | anon | resvn |
1421 +--------+------------+
1423 ^ ^ ^
1424 | | boundary is page aligned
1425 | VG_(brk_limit) -- no alignment constraint
1426 VG_(brk_base) -- page aligned -- does not move
1428 Both the anon part and the reservation part are always at least
1429 one page.
1432 /* Set the new data segment end to NEWBRK. If this succeeds, return
1433 NEWBRK, else return the current data segment end. */
1435 static Addr do_brk ( Addr newbrk, ThreadId tid )
1437 NSegment const* aseg;
1438 Addr newbrkP;
1439 SizeT delta;
1440 Bool debug = False;
1442 if (debug)
1443 VG_(printf)("\ndo_brk: brk_base=%#lx brk_limit=%#lx newbrk=%#lx\n",
1444 VG_(brk_base), VG_(brk_limit), newbrk);
1446 if (0) VG_(am_show_nsegments)(0, "in_brk");
1448 if (newbrk < VG_(brk_base))
1449 /* Clearly impossible. */
1450 goto bad;
1452 if (newbrk < VG_(brk_limit)) {
1453 /* shrinking the data segment. Be lazy and don't munmap the
1454 excess area. */
1455 NSegment const * seg = VG_(am_find_nsegment)(newbrk);
1456 vg_assert(seg);
1458 if (seg->hasT)
1459 VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk,
1460 "do_brk(shrink)" );
1461 /* Since we're being lazy and not unmapping pages, we have to
1462 zero out the area, so that if the area later comes back into
1463 circulation, it will be filled with zeroes, as if it really
1464 had been unmapped and later remapped. Be a bit paranoid and
1465 try hard to ensure we're not going to segfault by doing the
1466 write - check both ends of the range are in the same segment
1467 and that segment is writable. */
1468 NSegment const * seg2;
1470 seg2 = VG_(am_find_nsegment)( VG_(brk_limit) - 1 );
1471 vg_assert(seg2);
1473 if (seg == seg2 && seg->hasW)
1474 VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk );
1476 VG_(brk_limit) = newbrk;
1477 return newbrk;
1480 /* otherwise we're expanding the brk segment. */
1481 if (VG_(brk_limit) > VG_(brk_base))
1482 aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
1483 else
1484 aseg = VG_(am_find_nsegment)( VG_(brk_limit) );
1486 /* These should be assured by setup_client_dataseg in m_main. */
1487 vg_assert(aseg);
1488 vg_assert(aseg->kind == SkAnonC);
1490 if (newbrk <= aseg->end + 1) {
1491 /* still fits within the anon segment. */
1492 VG_(brk_limit) = newbrk;
1493 return newbrk;
1496 newbrkP = VG_PGROUNDUP(newbrk);
1497 delta = newbrkP - (aseg->end + 1);
1498 vg_assert(delta > 0);
1499 vg_assert(VG_IS_PAGE_ALIGNED(delta));
1501 Bool overflow = False;
1502 if (! VG_(am_extend_into_adjacent_reservation_client)( aseg->start, delta,
1503 &overflow)) {
1504 if (overflow) {
1505 static Bool alreadyComplained = False;
1506 if (!alreadyComplained) {
1507 alreadyComplained = True;
1508 if (VG_(clo_verbosity) > 0) {
1509 VG_(umsg)("brk segment overflow in thread #%u: "
1510 "can't grow to %#lx\n",
1511 tid, newbrkP);
1512 VG_(umsg)("(see section Limitations in user manual)\n");
1513 VG_(umsg)("NOTE: further instances of this message "
1514 "will not be shown\n");
1517 } else {
1518 if (VG_(clo_verbosity) > 0) {
1519 VG_(umsg)("Cannot map memory to grow brk segment in thread #%u "
1520 "to %#lx\n", tid, newbrkP);
1521 VG_(umsg)("(see section Limitations in user manual)\n");
1524 goto bad;
1527 VG_(brk_limit) = newbrk;
1528 return newbrk;
1530 bad:
1531 return VG_(brk_limit);
1535 /* ---------------------------------------------------------------------
1536 Vet file descriptors for sanity
1537 ------------------------------------------------------------------ */
1539 > - what does the "Bool soft" parameter mean?
1541 (Tom Hughes, 3 Oct 05):
1543 Whether or not to consider a file descriptor invalid if it is above
1544 the current soft limit.
1546 Basically if we are testing whether a newly created file descriptor is
1547 valid (in a post handler) then we set soft to true, and if we are
1548 testing whether a file descriptor that is about to be used (in a pre
1549 handler) is valid [viz, an already-existing fd] then we set it to false.
1551 The point is that if the (virtual) soft limit is lowered then any
1552 existing descriptors can still be read/written/closed etc (so long as
1553 they are below the valgrind reserved descriptors) but no new
1554 descriptors can be created above the new soft limit.
1556 (jrs 4 Oct 05: in which case, I've renamed it "isNewFd")
1559 /* Return true if we're allowed to use or create this fd */
1560 Bool ML_(fd_allowed)(Int fd, const HChar *syscallname, ThreadId tid,
1561 Bool isNewFd)
1563 Bool allowed = True;
1565 /* hard limits always apply */
1566 if (fd < 0 || fd >= VG_(fd_hard_limit))
1567 allowed = False;
1569 /* hijacking the output fds is never allowed */
1570 if (fd == VG_(log_output_sink).fd || fd == VG_(xml_output_sink).fd)
1571 allowed = False;
1573 /* if creating a new fd (rather than using an existing one), the
1574 soft limit must also be observed */
1575 if (isNewFd && fd >= VG_(fd_soft_limit))
1576 allowed = False;
1578 /* this looks like it ought to be included, but causes problems: */
1580 if (fd == 2 && VG_(debugLog_getLevel)() > 0)
1581 allowed = False;
1583 /* The difficulty is as follows: consider a program P which expects
1584 to be able to mess with (redirect) its own stderr (fd 2).
1585 Usually to deal with P we would issue command line flags to send
1586 logging somewhere other than stderr, so as not to disrupt P.
1587 The problem is that -d unilaterally hijacks stderr with no
1588 consultation with P. And so, if this check is enabled, P will
1589 work OK normally but fail if -d is issued.
1591 Basically -d is a hack and you take your chances when using it.
1592 It's very useful for low level debugging -- particularly at
1593 startup -- and having its presence change the behaviour of the
1594 client is exactly what we don't want. */
1596 /* croak? */
1597 if ((!allowed) && VG_(showing_core_errors)() ) {
1598 VG_(message)(Vg_UserMsg,
1599 "Warning: invalid file descriptor %d in syscall %s()\n",
1600 fd, syscallname);
1601 if (fd == VG_(log_output_sink).fd && VG_(log_output_sink).fd >= 0)
1602 VG_(message)(Vg_UserMsg,
1603 " Use --log-fd=<number> to select an alternative log fd.\n");
1604 if (fd == VG_(xml_output_sink).fd && VG_(xml_output_sink).fd >= 0)
1605 VG_(message)(Vg_UserMsg,
1606 " Use --xml-fd=<number> to select an alternative XML "
1607 "output fd.\n");
1608 // DDD: consider always printing this stack trace, it's useful.
1609 // Also consider also making this a proper core error, ie.
1610 // suppressible and all that.
1611 if (VG_(clo_verbosity) > 1) {
1612 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
1616 return allowed;
1620 /* ---------------------------------------------------------------------
1621 Deal with a bunch of socket-related syscalls
1622 ------------------------------------------------------------------ */
1624 /* ------ */
1626 void
1627 ML_(generic_PRE_sys_socketpair) ( ThreadId tid,
1628 UWord arg0, UWord arg1,
1629 UWord arg2, UWord arg3 )
1631 /* int socketpair(int d, int type, int protocol, int sv[2]); */
1632 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
1633 arg3, 2*sizeof(int) );
1636 SysRes
1637 ML_(generic_POST_sys_socketpair) ( ThreadId tid,
1638 SysRes res,
1639 UWord arg0, UWord arg1,
1640 UWord arg2, UWord arg3 )
1642 SysRes r = res;
1643 Int fd1 = ((Int*)arg3)[0];
1644 Int fd2 = ((Int*)arg3)[1];
1645 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1646 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1647 if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
1648 !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
1649 VG_(close)(fd1);
1650 VG_(close)(fd2);
1651 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1652 } else {
1653 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1654 if (VG_(clo_track_fds)) {
1655 ML_(record_fd_open_nameless)(tid, fd1);
1656 ML_(record_fd_open_nameless)(tid, fd2);
1659 return r;
1662 /* ------ */
1664 SysRes
1665 ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
1667 SysRes r = res;
1668 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1669 if (!ML_(fd_allowed)(sr_Res(res), "socket", tid, True)) {
1670 VG_(close)(sr_Res(res));
1671 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1672 } else {
1673 if (VG_(clo_track_fds))
1674 ML_(record_fd_open_nameless)(tid, sr_Res(res));
1676 return r;
1679 /* ------ */
1681 void
1682 ML_(generic_PRE_sys_bind) ( ThreadId tid,
1683 UWord arg0, UWord arg1, UWord arg2 )
1685 /* int bind(int sockfd, struct sockaddr *my_addr,
1686 int addrlen); */
1687 ML_(pre_mem_read_sockaddr) (
1688 tid, "socketcall.bind(my_addr.%s)",
1689 (struct vki_sockaddr *) arg1, arg2
1693 /* ------ */
1695 void
1696 ML_(generic_PRE_sys_accept) ( ThreadId tid,
1697 UWord arg0, UWord arg1, UWord arg2 )
1699 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1700 Addr addr_p = arg1;
1701 Addr addrlen_p = arg2;
1702 if (addr_p != (Addr)NULL)
1703 ML_(buf_and_len_pre_check) ( tid, addr_p, addrlen_p,
1704 "socketcall.accept(addr)",
1705 "socketcall.accept(addrlen_in)" );
1708 SysRes
1709 ML_(generic_POST_sys_accept) ( ThreadId tid,
1710 SysRes res,
1711 UWord arg0, UWord arg1, UWord arg2 )
1713 SysRes r = res;
1714 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1715 if (!ML_(fd_allowed)(sr_Res(res), "accept", tid, True)) {
1716 VG_(close)(sr_Res(res));
1717 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1718 } else {
1719 Addr addr_p = arg1;
1720 Addr addrlen_p = arg2;
1721 if (addr_p != (Addr)NULL)
1722 ML_(buf_and_len_post_check) ( tid, res, addr_p, addrlen_p,
1723 "socketcall.accept(addrlen_out)" );
1724 if (VG_(clo_track_fds))
1725 ML_(record_fd_open_nameless)(tid, sr_Res(res));
1727 return r;
1730 /* ------ */
1732 void
1733 ML_(generic_PRE_sys_sendto) ( ThreadId tid,
1734 UWord arg0, UWord arg1, UWord arg2,
1735 UWord arg3, UWord arg4, UWord arg5 )
1737 /* int sendto(int s, const void *msg, int len,
1738 unsigned int flags,
1739 const struct sockaddr *to, int tolen); */
1740 PRE_MEM_READ( "socketcall.sendto(msg)",
1741 arg1, /* msg */
1742 arg2 /* len */ );
1743 ML_(pre_mem_read_sockaddr) (
1744 tid, "socketcall.sendto(to.%s)",
1745 (struct vki_sockaddr *) arg4, arg5
1749 /* ------ */
1751 void
1752 ML_(generic_PRE_sys_send) ( ThreadId tid,
1753 UWord arg0, UWord arg1, UWord arg2 )
1755 /* int send(int s, const void *msg, size_t len, int flags); */
1756 PRE_MEM_READ( "socketcall.send(msg)",
1757 arg1, /* msg */
1758 arg2 /* len */ );
1762 /* ------ */
1764 void
1765 ML_(generic_PRE_sys_recvfrom) ( ThreadId tid,
1766 UWord arg0, UWord arg1, UWord arg2,
1767 UWord arg3, UWord arg4, UWord arg5 )
1769 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1770 struct sockaddr *from, int *fromlen); */
1771 Addr buf_p = arg1;
1772 Int len = arg2;
1773 Addr from_p = arg4;
1774 Addr fromlen_p = arg5;
1775 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1776 if (from_p != (Addr)NULL)
1777 ML_(buf_and_len_pre_check) ( tid, from_p, fromlen_p,
1778 "socketcall.recvfrom(from)",
1779 "socketcall.recvfrom(fromlen_in)" );
1782 void
1783 ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
1784 SysRes res,
1785 UWord arg0, UWord arg1, UWord arg2,
1786 UWord arg3, UWord arg4, UWord arg5 )
1788 Addr buf_p = arg1;
1789 Int len = arg2;
1790 Addr from_p = arg4;
1791 Addr fromlen_p = arg5;
1793 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1794 if (from_p != (Addr)NULL)
1795 ML_(buf_and_len_post_check) ( tid, res, from_p, fromlen_p,
1796 "socketcall.recvfrom(fromlen_out)" );
1797 POST_MEM_WRITE( buf_p, len );
1800 /* ------ */
1802 void
1803 ML_(generic_PRE_sys_recv) ( ThreadId tid,
1804 UWord arg0, UWord arg1, UWord arg2 )
1806 /* int recv(int s, void *buf, int len, unsigned int flags); */
1807 /* man 2 recv says:
1808 The recv call is normally used only on a connected socket
1809 (see connect(2)) and is identical to recvfrom with a NULL
1810 from parameter.
1812 PRE_MEM_WRITE( "socketcall.recv(buf)",
1813 arg1, /* buf */
1814 arg2 /* len */ );
1817 void
1818 ML_(generic_POST_sys_recv) ( ThreadId tid,
1819 UWord res,
1820 UWord arg0, UWord arg1, UWord arg2 )
1822 if (arg1 != 0) {
1823 POST_MEM_WRITE( arg1, /* buf */
1824 arg2 /* len */ );
1828 /* ------ */
1830 void
1831 ML_(generic_PRE_sys_connect) ( ThreadId tid,
1832 UWord arg0, UWord arg1, UWord arg2 )
1834 /* int connect(int sockfd,
1835 struct sockaddr *serv_addr, int addrlen ); */
1836 ML_(pre_mem_read_sockaddr) ( tid,
1837 "socketcall.connect(serv_addr.%s)",
1838 (struct vki_sockaddr *) arg1, arg2);
1841 /* ------ */
1843 void
1844 ML_(generic_PRE_sys_setsockopt) ( ThreadId tid,
1845 UWord arg0, UWord arg1, UWord arg2,
1846 UWord arg3, UWord arg4 )
1848 /* int setsockopt(int s, int level, int optname,
1849 const void *optval, int optlen); */
1850 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1851 arg3, /* optval */
1852 arg4 /* optlen */ );
1855 /* ------ */
1857 void
1858 ML_(generic_PRE_sys_getsockname) ( ThreadId tid,
1859 UWord arg0, UWord arg1, UWord arg2 )
1861 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1862 Addr name_p = arg1;
1863 Addr namelen_p = arg2;
1864 /* Nb: name_p cannot be NULL */
1865 ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p,
1866 "socketcall.getsockname(name)",
1867 "socketcall.getsockname(namelen_in)" );
1870 void
1871 ML_(generic_POST_sys_getsockname) ( ThreadId tid,
1872 SysRes res,
1873 UWord arg0, UWord arg1, UWord arg2 )
1875 Addr name_p = arg1;
1876 Addr namelen_p = arg2;
1877 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1878 ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
1879 "socketcall.getsockname(namelen_out)" );
1882 /* ------ */
1884 void
1885 ML_(generic_PRE_sys_getpeername) ( ThreadId tid,
1886 UWord arg0, UWord arg1, UWord arg2 )
1888 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1889 Addr name_p = arg1;
1890 Addr namelen_p = arg2;
1891 /* Nb: name_p cannot be NULL */
1892 ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p,
1893 "socketcall.getpeername(name)",
1894 "socketcall.getpeername(namelen_in)" );
1897 void
1898 ML_(generic_POST_sys_getpeername) ( ThreadId tid,
1899 SysRes res,
1900 UWord arg0, UWord arg1, UWord arg2 )
1902 Addr name_p = arg1;
1903 Addr namelen_p = arg2;
1904 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1905 ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
1906 "socketcall.getpeername(namelen_out)" );
1909 /* ------ */
1911 void
1912 ML_(generic_PRE_sys_sendmsg) ( ThreadId tid, const HChar *name,
1913 struct vki_msghdr *msg )
1915 msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_read_sendmsg, False );
1918 /* ------ */
1920 void
1921 ML_(generic_PRE_sys_recvmsg) ( ThreadId tid, const HChar *name,
1922 struct vki_msghdr *msg )
1924 msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_write_recvmsg, True );
1927 void
1928 ML_(generic_POST_sys_recvmsg) ( ThreadId tid, const HChar *name,
1929 struct vki_msghdr *msg, UInt length )
1931 msghdr_foreachfield( tid, name, msg, length, post_mem_write_recvmsg, True );
1932 check_cmsg_for_fds( tid, msg );
1936 /* ---------------------------------------------------------------------
1937 Deal with a bunch of IPC related syscalls
1938 ------------------------------------------------------------------ */
1940 /* ------ */
1942 void
1943 ML_(generic_PRE_sys_semop) ( ThreadId tid,
1944 UWord arg0, UWord arg1, UWord arg2 )
1946 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1947 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1950 /* ------ */
1952 void
1953 ML_(generic_PRE_sys_semtimedop) ( ThreadId tid,
1954 UWord arg0, UWord arg1,
1955 UWord arg2, UWord arg3 )
1957 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1958 struct timespec *timeout); */
1959 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1960 if (arg3 != 0)
1961 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1964 /* ------ */
1966 static
1967 UInt get_sem_count( Int semid )
1969 union vki_semun arg;
1970 SysRes res;
1972 # if defined(__NR_semctl)
1973 # if defined(VGO_darwin)
1974 /* Darwin has no specific 64 bit semid_ds, but has __NR_semctl. */
1975 struct vki_semid_ds buf;
1976 arg.buf = &buf;
1977 # else
1978 struct vki_semid64_ds buf;
1979 arg.buf64 = &buf;
1980 # endif
1981 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
1982 if (sr_isError(res))
1983 return 0;
1985 return buf.sem_nsems;
1986 # elif defined(__NR___semctl) /* FreeBSD */
1987 struct vki_semid_ds buf;
1988 arg.buf = &buf;
1989 res = VG_(do_syscall4)(__NR___semctl, semid, 0, VKI_IPC_STAT, (RegWord)&arg);
1991 if (sr_isError(res))
1992 return 0;
1994 // both clang-tidy and coverity complain about this but I think they are both wrong
1995 return buf.sem_nsems;
1996 # elif defined(__NR_semsys) /* Solaris */
1997 struct vki_semid_ds buf;
1998 arg.buf = &buf;
1999 res = VG_(do_syscall5)(__NR_semsys, VKI_SEMCTL, semid, 0, VKI_IPC_STAT,
2000 *(UWord *)&arg);
2001 if (sr_isError(res))
2002 return 0;
2004 return buf.sem_nsems;
2006 # else
2007 struct vki_semid_ds buf;
2008 arg.buf = &buf;
2009 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
2010 VKI_IPC_STAT, (UWord)&arg);
2011 if (sr_isError(res))
2012 return 0;
2014 return buf.sem_nsems;
2015 # endif
2018 void
2019 ML_(generic_PRE_sys_semctl) ( ThreadId tid,
2020 UWord arg0, UWord arg1,
2021 UWord arg2, UWord arg3 )
2023 /* int semctl(int semid, int semnum, int cmd, ...); */
2024 union vki_semun arg = *(union vki_semun *)&arg3;
2025 UInt nsems;
2026 switch (arg2 /* cmd */) {
2027 #if defined(VKI_IPC_INFO)
2028 case VKI_IPC_INFO:
2029 case VKI_SEM_INFO:
2030 #if defined(VKI_IPC_64)
2031 case VKI_IPC_INFO|VKI_IPC_64:
2032 case VKI_SEM_INFO|VKI_IPC_64:
2033 #endif
2034 #if defined(VGO_freebsd)
2035 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
2036 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2037 #else
2038 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
2039 (Addr)arg.buf, sizeof(struct vki_seminfo) );
2040 #endif
2041 break;
2042 #endif
2044 case VKI_IPC_STAT:
2045 #if defined(VKI_SEM_STAT)
2046 case VKI_SEM_STAT:
2047 #endif
2048 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
2049 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2050 break;
2052 #if defined(VKI_IPC_64)
2053 case VKI_IPC_STAT|VKI_IPC_64:
2054 #if defined(VKI_SEM_STAT)
2055 case VKI_SEM_STAT|VKI_IPC_64:
2056 #endif
2057 #endif
2058 #if defined(VKI_IPC_STAT64)
2059 case VKI_IPC_STAT64:
2060 #endif
2061 #if defined(VKI_IPC_64) || defined(VKI_IPC_STAT64)
2062 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
2063 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2064 break;
2065 #endif
2067 case VKI_IPC_SET:
2068 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
2069 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2070 break;
2072 #if defined(VKI_IPC_64)
2073 case VKI_IPC_SET|VKI_IPC_64:
2074 #endif
2075 #if defined(VKI_IPC_SET64)
2076 case VKI_IPC_SET64:
2077 #endif
2078 #if defined(VKI_IPC64) || defined(VKI_IPC_SET64)
2079 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
2080 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2081 break;
2082 #endif
2084 case VKI_GETALL:
2085 #if defined(VKI_IPC_64)
2086 case VKI_GETALL|VKI_IPC_64:
2087 #endif
2088 nsems = get_sem_count( arg0 );
2089 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
2090 (Addr)arg.array, sizeof(unsigned short) * nsems );
2091 break;
2093 case VKI_SETALL:
2094 #if defined(VKI_IPC_64)
2095 case VKI_SETALL|VKI_IPC_64:
2096 #endif
2097 nsems = get_sem_count( arg0 );
2098 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
2099 (Addr)arg.array, sizeof(unsigned short) * nsems );
2100 break;
2104 void
2105 ML_(generic_POST_sys_semctl) ( ThreadId tid,
2106 UWord res,
2107 UWord arg0, UWord arg1,
2108 UWord arg2, UWord arg3 )
2110 union vki_semun arg = *(union vki_semun *)&arg3;
2111 UInt nsems;
2112 switch (arg2 /* cmd */) {
2113 #if defined(VKI_IPC_INFO)
2114 case VKI_IPC_INFO:
2115 case VKI_SEM_INFO:
2116 #if defined(VKI_IPC_64)
2117 case VKI_IPC_INFO|VKI_IPC_64:
2118 case VKI_SEM_INFO|VKI_IPC_64:
2119 #endif
2120 #if defined(VGO_freebsd)
2121 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2122 #else
2123 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
2124 #endif
2125 break;
2126 #endif
2128 case VKI_IPC_STAT:
2129 #if defined(VKI_SEM_STAT)
2130 case VKI_SEM_STAT:
2131 #endif
2132 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2133 break;
2135 #if defined(VKI_IPC_64)
2136 case VKI_IPC_STAT|VKI_IPC_64:
2137 case VKI_SEM_STAT|VKI_IPC_64:
2138 #endif
2139 #if defined(VKI_IPC_STAT64)
2140 case VKI_IPC_STAT64:
2141 #endif
2142 #if defined(VKI_IPC_64) || defined(VKI_IPC_STAT64)
2143 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2144 break;
2145 #endif
2147 case VKI_GETALL:
2148 #if defined(VKI_IPC_64)
2149 case VKI_GETALL|VKI_IPC_64:
2150 #endif
2151 nsems = get_sem_count( arg0 );
2152 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
2153 break;
2157 /* ------ */
2159 /* ------ */
2161 static
2162 SizeT get_shm_size ( Int shmid )
2165 * The excluded platforms below gained direct shmctl in Linux 5.1. Keep
2166 * using ipc-multiplexed shmctl to keep compatibility with older kernel
2167 * versions.
2169 #if defined(__NR_shmctl) && \
2170 !defined(VGP_x86_linux) && !defined(VGP_mips32_linux) && \
2171 !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) && \
2172 !defined(VGP_ppc64le_linux) && !defined(VGP_s390x_linux)
2173 # ifdef VKI_IPC_64
2174 struct vki_shmid64_ds buf;
2176 * On Linux, the following ABIs use old shmid_ds by default with direct
2177 * shmctl and require IPC_64 for shmid64_ds (i.e. the direct syscall is
2178 * mapped to sys_old_shmctl):
2179 * alpha, arm, microblaze, mips n32/n64, xtensa
2180 * Other Linux ABIs use shmid64_ds by default and do not recognize IPC_64
2181 * with the direct shmctl syscall (but still recognize it for the
2182 * ipc-multiplexed version if that exists for the ABI).
2184 # if defined(VGO_linux) && !defined(VGP_arm_linux) && !defined(VGP_mips64_linux)
2185 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid,
2186 VKI_IPC_STAT, (UWord)&buf);
2187 # else
2188 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid,
2189 VKI_IPC_STAT|VKI_IPC_64, (UWord)&buf);
2190 # endif
2191 # else /* !def VKI_IPC_64 */
2192 struct vki_shmid_ds buf;
2193 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
2194 # endif /* def VKI_IPC_64 */
2195 #elif defined(__NR_shmsys) /* Solaris */
2196 struct vki_shmid_ds buf;
2197 SysRes __res = VG_(do_syscall4)(__NR_shmsys, VKI_SHMCTL, shmid, VKI_IPC_STAT,
2198 (UWord)&buf);
2199 #else
2200 struct vki_shmid_ds buf;
2201 SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
2202 VKI_IPC_STAT, 0, (UWord)&buf);
2203 #endif
2204 if (sr_isError(__res))
2205 return 0;
2207 return (SizeT) buf.shm_segsz;
2210 UWord
2211 ML_(generic_PRE_sys_shmat) ( ThreadId tid,
2212 UWord arg0, UWord arg1, UWord arg2 )
2214 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
2215 SizeT segmentSize = get_shm_size ( arg0 );
2216 UWord tmp;
2217 Bool ok;
2218 if (arg1 == 0) {
2219 /* arm-linux only: work around the fact that
2220 VG_(am_get_advisory_client_simple) produces something that is
2221 VKI_PAGE_SIZE aligned, whereas what we want is something
2222 VKI_SHMLBA aligned, and VKI_SHMLBA >= VKI_PAGE_SIZE. Hence
2223 increase the request size by VKI_SHMLBA - VKI_PAGE_SIZE and
2224 then round the result up to the next VKI_SHMLBA boundary.
2225 See bug 222545 comment 15. So far, arm-linux is the only
2226 platform where this is known to be necessary. */
2227 vg_assert(VKI_SHMLBA >= VKI_PAGE_SIZE);
2228 if (VKI_SHMLBA > VKI_PAGE_SIZE) {
2229 segmentSize += VKI_SHMLBA - VKI_PAGE_SIZE;
2231 tmp = VG_(am_get_advisory_client_simple)(0, segmentSize, &ok);
2232 if (ok) {
2233 if (VKI_SHMLBA > VKI_PAGE_SIZE) {
2234 arg1 = VG_ROUNDUP(tmp, VKI_SHMLBA);
2235 } else {
2236 arg1 = tmp;
2240 else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
2241 arg1 = 0;
2242 return arg1;
2245 void
2246 ML_(generic_POST_sys_shmat) ( ThreadId tid,
2247 UWord res,
2248 UWord arg0, UWord arg1, UWord arg2 )
2250 SizeT segmentSize = VG_PGROUNDUP(get_shm_size(arg0));
2251 if ( segmentSize > 0 ) {
2252 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
2253 Bool d;
2255 if (arg2 & VKI_SHM_RDONLY)
2256 prot &= ~VKI_PROT_WRITE;
2257 /* It isn't exactly correct to pass 0 for the fd and offset
2258 here. The kernel seems to think the corresponding section
2259 does have dev/ino numbers:
2261 04e52000-04ec8000 rw-s 00000000 00:06 1966090 /SYSV00000000 (deleted)
2263 However there is no obvious way to find them. In order to
2264 cope with the discrepancy, aspacem's sync checker omits the
2265 dev/ino correspondence check in cases where V does not know
2266 the dev/ino. */
2267 d = VG_(am_notify_client_shmat)( res, segmentSize, prot );
2269 /* we don't distinguish whether it's read-only or
2270 * read-write -- it doesn't matter really. */
2271 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False,
2272 0/*di_handle*/ );
2273 if (d)
2274 VG_(discard_translations)( (Addr)res,
2275 (ULong)VG_PGROUNDUP(segmentSize),
2276 "ML_(generic_POST_sys_shmat)" );
2280 /* ------ */
2282 Bool
2283 ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
2285 /* int shmdt(const void *shmaddr); */
2286 return ML_(valid_client_addr)(arg0, 1, tid, "shmdt");
2289 void
2290 ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
2292 NSegment const* s = VG_(am_find_nsegment)(arg0);
2294 if (s != NULL) {
2295 Addr s_start = s->start;
2296 SizeT s_len = s->end+1 - s->start;
2297 Bool d;
2299 vg_assert(s->kind == SkShmC);
2300 vg_assert(s->start == arg0);
2302 d = VG_(am_notify_munmap)(s_start, s_len);
2303 s = NULL; /* s is now invalid */
2304 VG_TRACK( die_mem_munmap, s_start, s_len );
2305 if (d)
2306 VG_(discard_translations)( s_start,
2307 (ULong)s_len,
2308 "ML_(generic_POST_sys_shmdt)" );
2311 /* ------ */
2313 void
2314 ML_(generic_PRE_sys_shmctl) ( ThreadId tid,
2315 UWord arg0, UWord arg1, UWord arg2 )
2317 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
2318 switch (arg1 /* cmd */) {
2319 #if defined(VKI_IPC_INFO)
2320 case VKI_IPC_INFO:
2321 # if defined(VGO_freebsd)
2322 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2323 arg2, sizeof(struct vki_shmid_ds) );
2324 # else
2325 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2326 arg2, sizeof(struct vki_shminfo) );
2327 # endif
2328 break;
2329 #if defined(VKI_IPC_64)
2330 case VKI_IPC_INFO|VKI_IPC_64:
2331 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2332 arg2, sizeof(struct vki_shminfo64) );
2333 break;
2334 #endif
2335 #endif
2337 #if defined(VKI_SHM_INFO)
2338 case VKI_SHM_INFO:
2339 #if defined(VKI_IPC_64)
2340 case VKI_SHM_INFO|VKI_IPC_64:
2341 #endif
2342 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
2343 arg2, sizeof(struct vki_shm_info) );
2344 break;
2345 #endif
2347 case VKI_IPC_STAT:
2348 #if defined(VKI_SHM_STAT)
2349 case VKI_SHM_STAT:
2350 #endif
2351 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
2352 arg2, sizeof(struct vki_shmid_ds) );
2353 break;
2355 #if defined(VKI_IPC_64)
2356 case VKI_IPC_STAT|VKI_IPC_64:
2357 case VKI_SHM_STAT|VKI_IPC_64:
2358 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
2359 arg2, sizeof(struct vki_shmid64_ds) );
2360 break;
2361 #endif
2363 case VKI_IPC_SET:
2364 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
2365 arg2, sizeof(struct vki_shmid_ds) );
2366 break;
2368 #if defined(VKI_IPC_64)
2369 case VKI_IPC_SET|VKI_IPC_64:
2370 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
2371 arg2, sizeof(struct vki_shmid64_ds) );
2372 break;
2373 #endif
2377 void
2378 ML_(generic_POST_sys_shmctl) ( ThreadId tid,
2379 UWord res,
2380 UWord arg0, UWord arg1, UWord arg2 )
2382 switch (arg1 /* cmd */) {
2383 #if defined(VKI_IPC_INFO)
2384 case VKI_IPC_INFO:
2385 # if defined(VGO_freebsd)
2386 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
2387 # else
2388 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
2389 # endif
2390 break;
2391 #if defined(VKI_IPC_64)
2392 case VKI_IPC_INFO|VKI_IPC_64:
2393 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
2394 break;
2395 #endif
2396 #endif
2398 #if defined(VKI_SHM_INFO)
2399 case VKI_SHM_INFO:
2400 case VKI_SHM_INFO|VKI_IPC_64:
2401 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
2402 break;
2403 #endif
2405 case VKI_IPC_STAT:
2406 #if defined(VKI_SHM_STAT)
2407 case VKI_SHM_STAT:
2408 #endif
2409 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
2410 break;
2412 #if defined(VKI_IPC_64)
2413 case VKI_IPC_STAT|VKI_IPC_64:
2414 case VKI_SHM_STAT|VKI_IPC_64:
2415 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
2416 break;
2417 #endif
2423 /* ---------------------------------------------------------------------
2424 Generic handler for mmap
2425 ------------------------------------------------------------------ */
2428 * Although mmap is specified by POSIX and the argument are generally
2429 * consistent across platforms the precise details of the low level
2430 * argument passing conventions differ. For example:
2432 * - On x86-linux there is mmap (aka old_mmap) which takes the
2433 * arguments in a memory block and the offset in bytes; and
2434 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
2435 * way and the offset in pages.
2437 * - On ppc32-linux there is mmap (aka sys_mmap) which takes the
2438 * arguments in the normal way and the offset in bytes; and
2439 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
2440 * way and the offset in pages.
2442 * - On amd64-linux everything is simple and there is just the one
2443 * call, mmap (aka sys_mmap) which takes the arguments in the
2444 * normal way and the offset in bytes.
2446 * - On s390x-linux there is mmap (aka old_mmap) which takes the
2447 * arguments in a memory block and the offset in bytes. mmap2
2448 * is also available (but not exported via unistd.h) with
2449 * arguments in a memory block and the offset in pages.
2451 * To cope with all this we provide a generic handler function here
2452 * and then each platform implements one or more system call handlers
2453 * which call this generic routine after extracting and normalising
2454 * the arguments.
2457 SysRes
2458 ML_(generic_PRE_sys_mmap) ( ThreadId tid,
2459 UWord arg1, UWord arg2, UWord arg3,
2460 UWord arg4, UWord arg5, Off64T arg6 )
2462 Addr advised;
2463 SysRes sres;
2464 MapRequest mreq;
2465 Bool mreq_ok;
2467 # if defined(VGO_darwin)
2468 // Nb: we can't use this on Darwin, it has races:
2469 // * needs to RETRY if advisory succeeds but map fails
2470 // (could have been some other thread in a nonblocking call)
2471 // * needs to not use fixed-position mmap() on Darwin
2472 // (mmap will cheerfully smash whatever's already there, which might
2473 // be a new mapping from some other thread in a nonblocking call)
2474 VG_(core_panic)("can't use ML_(generic_PRE_sys_mmap) on Darwin");
2475 # endif
2477 if (arg2 == 0) {
2478 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
2479 shall be established. */
2480 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2483 if (!VG_IS_PAGE_ALIGNED(arg1)) {
2484 /* zap any misaligned addresses. */
2485 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
2486 to fail. Here, we catch them all. */
2487 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2490 if (!VG_IS_PAGE_ALIGNED(arg6)) {
2491 /* zap any misaligned offsets. */
2492 /* SuSV3 says: The off argument is constrained to be aligned and
2493 sized according to the value returned by sysconf() when
2494 passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
2495 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2498 /* Figure out what kind of allocation constraints there are
2499 (fixed/hint/any), and ask aspacem what we should do. */
2500 mreq.start = arg1;
2501 mreq.len = arg2;
2502 if (arg4 & VKI_MAP_FIXED) {
2503 mreq.rkind = MFixed;
2504 } else
2505 #if defined(VKI_MAP_ALIGN) /* Solaris specific */
2506 if (arg4 & VKI_MAP_ALIGN) {
2507 mreq.rkind = MAlign;
2508 if (mreq.start == 0) {
2509 mreq.start = VKI_PAGE_SIZE;
2511 /* VKI_MAP_FIXED and VKI_MAP_ALIGN don't like each other. */
2512 arg4 &= ~VKI_MAP_ALIGN;
2513 } else
2514 #endif
2515 if (arg1 != 0) {
2516 mreq.rkind = MHint;
2517 } else {
2518 mreq.rkind = MAny;
2521 /* Enquire ... */
2522 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2523 if (!mreq_ok) {
2524 /* Our request was bounced, so we'd better fail. */
2525 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2528 # if defined(VKI_MAP_32BIT)
2529 /* MAP_32BIT is royally unportable, so if the client asks for it, try our
2530 best to make it work (but without complexifying aspacemgr).
2531 If the user requested MAP_32BIT, the mmap-ed space must be in the
2532 first 2GB of the address space. So, return ENOMEM if aspacemgr
2533 advisory is above the first 2GB. If MAP_FIXED is also requested,
2534 MAP_32BIT has to be ignored.
2535 Assumption about aspacemgr behaviour: aspacemgr scans the address space
2536 from low addresses to find a free segment. No special effort is done
2537 to keep the first 2GB 'free' for this MAP_32BIT. So, this will often
2538 fail once the program has already allocated significant memory. */
2539 if ((arg4 & VKI_MAP_32BIT) && !(arg4 & VKI_MAP_FIXED)) {
2540 if (advised + arg2 >= 0x80000000)
2541 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
2543 # endif
2545 /* Otherwise we're OK (so far). Install aspacem's choice of
2546 address, and let the mmap go through. */
2547 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2548 arg4 | VKI_MAP_FIXED,
2549 arg5, arg6);
2551 # if defined(VKI_MAP_32BIT)
2552 /* No recovery trial if the advisory was not accepted. */
2553 if ((arg4 & VKI_MAP_32BIT) && !(arg4 & VKI_MAP_FIXED)
2554 && sr_isError(sres)) {
2555 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
2557 # endif
2559 /* A refinement: it may be that the kernel refused aspacem's choice
2560 of address. If we were originally asked for a hinted mapping,
2561 there is still a last chance: try again at any address.
2562 Hence: */
2563 if (mreq.rkind == MHint && sr_isError(sres)) {
2564 mreq.start = 0;
2565 mreq.len = arg2;
2566 mreq.rkind = MAny;
2567 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2568 if (!mreq_ok) {
2569 /* Our request was bounced, so we'd better fail. */
2570 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2572 /* and try again with the kernel */
2573 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2574 arg4 | VKI_MAP_FIXED,
2575 arg5, arg6);
2578 /* Yet another refinement : sometimes valgrind chooses an address
2579 which is not acceptable by the kernel. This at least happens
2580 when mmap-ing huge pages, using the flag MAP_HUGETLB.
2581 valgrind aspacem does not know about huge pages, and modifying
2582 it to handle huge pages is not straightforward (e.g. need
2583 to understand special file system mount options).
2584 So, let's just redo an mmap, without giving any constraint to
2585 the kernel. If that succeeds, check with aspacem that the returned
2586 address is acceptable.
2587 This will give a similar effect as if the user would have
2588 hinted that address.
2589 The aspacem state will be correctly updated afterwards.
2590 We however cannot do this last refinement when the user asked
2591 for a fixed mapping, as the user asked a specific address. */
2592 if (sr_isError(sres) && !(arg4 & VKI_MAP_FIXED)) {
2593 advised = 0;
2594 /* try mmap with NULL address and without VKI_MAP_FIXED
2595 to let the kernel decide. */
2596 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2597 arg4,
2598 arg5, arg6);
2599 if (!sr_isError(sres)) {
2600 /* The kernel is supposed to know what it is doing, but let's
2601 do a last sanity check anyway, as if the chosen address had
2602 been initially hinted by the client. The whole point of this
2603 last try was to allow mmap of huge pages to succeed without
2604 making aspacem understand them, on the other hand the kernel
2605 does not know about valgrind reservations, so this mapping
2606 can end up in free space and reservations. */
2607 mreq.start = (Addr)sr_Res(sres);
2608 mreq.len = arg2;
2609 mreq.rkind = MHint;
2610 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2611 vg_assert(mreq_ok && advised == mreq.start);
2615 if (!sr_isError(sres)) {
2616 ULong di_handle;
2617 /* Notify aspacem. */
2618 notify_core_of_mmap(
2619 (Addr)sr_Res(sres), /* addr kernel actually assigned */
2620 arg2, /* length */
2621 arg3, /* prot */
2622 arg4, /* the original flags value */
2623 arg5, /* fd */
2624 arg6 /* offset */
2626 /* Load symbols? */
2627 di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres),
2628 False/*allow_SkFileV*/, (Int)arg5 );
2629 /* Notify the tool. */
2630 notify_tool_of_mmap(
2631 (Addr)sr_Res(sres), /* addr kernel actually assigned */
2632 arg2, /* length */
2633 arg3, /* prot */
2634 di_handle /* so the tool can refer to the read debuginfo later,
2635 if it wants. */
2639 /* Stay sane */
2640 if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED))
2641 vg_assert(sr_Res(sres) == arg1);
2643 return sres;
2647 /* ---------------------------------------------------------------------
2648 The Main Entertainment ... syscall wrappers
2649 ------------------------------------------------------------------ */
2651 /* Note: the PRE() and POST() wrappers are for the actual functions
2652 implementing the system calls in the OS kernel. These mostly have
2653 names like sys_write(); a few have names like old_mmap(). See the
2654 comment for ML_(syscall_table)[] for important info about the __NR_foo
2655 constants and their relationship to the sys_foo() functions.
2657 Some notes about names used for syscalls and args:
2658 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
2659 ambiguity.
2661 - For error messages, we generally use a somewhat generic name
2662 for the syscall (eg. "write" rather than "sys_write"). This should be
2663 good enough for the average user to understand what is happening,
2664 without confusing them with names like "sys_write".
2666 - Also, for error messages the arg names are mostly taken from the man
2667 pages (even though many of those man pages are really for glibc
2668 functions of the same name), rather than from the OS kernel source,
2669 for the same reason -- a user presented with a "bogus foo(bar)" arg
2670 will most likely look at the "foo" man page to see which is the "bar"
2671 arg.
2673 Note that we use our own vki_* types. The one exception is in
2674 PRE_REG_READn calls, where pointer types haven't been changed, because
2675 they don't need to be -- eg. for "foo*" to be used, the type foo need not
2676 be visible.
2678 XXX: some of these are arch-specific, and should be factored out.
2681 #define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
2682 #define POST(name) DEFN_POST_TEMPLATE(generic, name)
2684 PRE(sys_exit)
2686 ThreadState* tst;
2687 /* simple; just make this thread exit */
2688 PRINT("exit( %ld )", SARG1);
2689 PRE_REG_READ1(void, "exit", int, status);
2690 tst = VG_(get_ThreadState)(tid);
2691 /* Set the thread's status to be exiting, then claim that the
2692 syscall succeeded. */
2693 tst->exitreason = VgSrc_ExitThread;
2694 tst->os_state.exitcode = ARG1;
2695 SET_STATUS_Success(0);
2698 PRE(sys_ni_syscall)
2700 PRINT("unimplemented (by the kernel) syscall: %s! (ni_syscall)\n",
2701 VG_SYSNUM_STRING(SYSNO));
2702 PRE_REG_READ0(long, "ni_syscall");
2703 SET_STATUS_Failure( VKI_ENOSYS );
2706 PRE(sys_iopl)
2708 PRINT("sys_iopl ( %" FMT_REGWORD "u )", ARG1);
2709 PRE_REG_READ1(long, "iopl", unsigned long, level);
2712 PRE(sys_fsync)
2714 *flags |= SfMayBlock;
2715 PRINT("sys_fsync ( %" FMT_REGWORD "u )", ARG1);
2716 PRE_REG_READ1(long, "fsync", unsigned int, fd);
2719 PRE(sys_fdatasync)
2721 *flags |= SfMayBlock;
2722 PRINT("sys_fdatasync ( %" FMT_REGWORD "u )", ARG1);
2723 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
2726 PRE(sys_msync)
2728 *flags |= SfMayBlock;
2729 PRINT("sys_msync ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2730 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
2731 PRE_REG_READ3(long, "msync",
2732 unsigned long, start, vki_size_t, length, int, flags);
2733 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
2736 // Nb: getpmsg() and putpmsg() are special additional syscalls used in early
2737 // versions of LiS (Linux Streams). They are not part of the kernel.
2738 // Therefore, we have to provide this type ourself, rather than getting it
2739 // from the kernel sources.
2740 struct vki_pmsg_strbuf {
2741 int maxlen; /* no. of bytes in buffer */
2742 int len; /* no. of bytes returned */
2743 vki_caddr_t buf; /* pointer to data */
2745 PRE(sys_getpmsg)
2747 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
2748 struct vki_pmsg_strbuf *ctrl;
2749 struct vki_pmsg_strbuf *data;
2750 *flags |= SfMayBlock;
2751 PRINT("sys_getpmsg ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
2752 FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,
2753 ARG2, ARG3, ARG4, ARG5);
2754 PRE_REG_READ5(int, "getpmsg",
2755 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2756 int *, bandp, int *, flagsp);
2757 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2758 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2759 if (ctrl && ctrl->maxlen > 0)
2760 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
2761 if (data && data->maxlen > 0)
2762 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
2763 if (ARG4)
2764 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
2765 if (ARG5)
2766 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
2768 POST(sys_getpmsg)
2770 struct vki_pmsg_strbuf *ctrl;
2771 struct vki_pmsg_strbuf *data;
2772 vg_assert(SUCCESS);
2773 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2774 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2775 if (RES == 0 && ctrl && ctrl->len > 0) {
2776 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
2778 if (RES == 0 && data && data->len > 0) {
2779 POST_MEM_WRITE( (Addr)data->buf, data->len);
2783 PRE(sys_putpmsg)
2785 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
2786 struct vki_pmsg_strbuf *ctrl;
2787 struct vki_pmsg_strbuf *data;
2788 *flags |= SfMayBlock;
2789 PRINT("sys_putpmsg ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD
2790 "x, %ld, %ld )", SARG1, ARG2, ARG3, SARG4, SARG5);
2791 PRE_REG_READ5(int, "putpmsg",
2792 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2793 int, band, int, flags);
2794 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2795 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2796 if (ctrl && ctrl->len > 0)
2797 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
2798 if (data && data->len > 0)
2799 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
2802 PRE(sys_getitimer)
2804 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2805 PRINT("sys_getitimer ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2806 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
2808 PRE_timeval_WRITE( "getitimer(&value->it_interval)", &(value->it_interval));
2809 PRE_timeval_WRITE( "getitimer(&value->it_value)", &(value->it_value));
2812 POST(sys_getitimer)
2814 if (ARG2 != (Addr)NULL) {
2815 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2816 POST_timeval_WRITE( &(value->it_interval) );
2817 POST_timeval_WRITE( &(value->it_value) );
2821 PRE(sys_setitimer)
2823 PRINT("sys_setitimer ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2824 SARG1, ARG2, ARG3);
2825 PRE_REG_READ3(long, "setitimer",
2826 int, which,
2827 struct itimerval *, value, struct itimerval *, ovalue);
2828 if (ARG2 != (Addr)NULL) {
2829 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2830 PRE_timeval_READ( "setitimer(&value->it_interval)",
2831 &(value->it_interval));
2832 PRE_timeval_READ( "setitimer(&value->it_value)",
2833 &(value->it_value));
2835 if (ARG3 != (Addr)NULL) {
2836 struct vki_itimerval *ovalue = (struct vki_itimerval*)(Addr)ARG3;
2837 PRE_timeval_WRITE( "setitimer(&ovalue->it_interval)",
2838 &(ovalue->it_interval));
2839 PRE_timeval_WRITE( "setitimer(&ovalue->it_value)",
2840 &(ovalue->it_value));
2844 POST(sys_setitimer)
2846 if (ARG3 != (Addr)NULL) {
2847 struct vki_itimerval *ovalue = (struct vki_itimerval*)(Addr)ARG3;
2848 POST_timeval_WRITE( &(ovalue->it_interval) );
2849 POST_timeval_WRITE( &(ovalue->it_value) );
2853 PRE(sys_chroot)
2855 PRINT("sys_chroot ( %#" FMT_REGWORD "x )", ARG1);
2856 PRE_REG_READ1(long, "chroot", const char *, path);
2857 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
2860 PRE(sys_madvise)
2862 *flags |= SfMayBlock;
2863 PRINT("sys_madvise ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
2864 ARG1, ARG2, SARG3);
2865 PRE_REG_READ3(long, "madvise",
2866 unsigned long, start, vki_size_t, length, int, advice);
2869 #if HAVE_MREMAP
2870 PRE(sys_mremap)
2872 // Nb: this is different to the glibc version described in the man pages,
2873 // which lacks the fifth 'new_address' argument.
2874 if (ARG4 & VKI_MREMAP_FIXED) {
2875 PRINT("sys_mremap ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2876 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2877 ARG1, ARG2, ARG3, ARG4, ARG5);
2878 PRE_REG_READ5(unsigned long, "mremap",
2879 unsigned long, old_addr, unsigned long, old_size,
2880 unsigned long, new_size, unsigned long, flags,
2881 unsigned long, new_addr);
2882 } else {
2883 PRINT("sys_mremap ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2884 FMT_REGWORD "u, 0x%" FMT_REGWORD "x )",
2885 ARG1, ARG2, ARG3, ARG4);
2886 PRE_REG_READ4(unsigned long, "mremap",
2887 unsigned long, old_addr, unsigned long, old_size,
2888 unsigned long, new_size, unsigned long, flags);
2890 SET_STATUS_from_SysRes(
2891 do_mremap((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
2894 #endif /* HAVE_MREMAP */
2896 PRE(sys_nice)
2898 PRINT("sys_nice ( %ld )", SARG1);
2899 PRE_REG_READ1(long, "nice", int, inc);
2902 PRE(sys_mlock2)
2904 *flags |= SfMayBlock;
2905 PRINT("sys_mlock2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
2906 PRE_REG_READ2(int, "mlock2", void*, addr, vki_size_t, len);
2909 PRE(sys_mlock)
2911 *flags |= SfMayBlock;
2912 PRINT("sys_mlock ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
2913 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
2916 PRE(sys_munlock)
2918 *flags |= SfMayBlock;
2919 PRINT("sys_munlock ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
2920 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
2923 PRE(sys_mlockall)
2925 *flags |= SfMayBlock;
2926 PRINT("sys_mlockall ( %" FMT_REGWORD "x )", ARG1);
2927 PRE_REG_READ1(long, "mlockall", int, flags);
2930 PRE(sys_setpriority)
2932 PRINT("sys_setpriority ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2933 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
2936 PRE(sys_getpriority)
2938 PRINT("sys_getpriority ( %ld, %ld )", SARG1, SARG2);
2939 PRE_REG_READ2(long, "getpriority", int, which, int, who);
2942 #if !defined(VGO_freebsd)
2943 PRE(sys_pwrite64)
2945 *flags |= SfMayBlock;
2946 #if VG_WORDSIZE == 4
2947 PRINT("sys_pwrite64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
2948 FMT_REGWORD "u, %lld )", ARG1, ARG2, ARG3, (Long)MERGE64(ARG4,ARG5));
2949 PRE_REG_READ5(ssize_t, "pwrite64",
2950 unsigned int, fd, const char *, buf, vki_size_t, count,
2951 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
2952 #elif VG_WORDSIZE == 8
2953 PRINT("sys_pwrite64 ( %lu, %#lx, %lu, %ld )",
2954 ARG1, ARG2, ARG3, SARG4);
2955 PRE_REG_READ4(ssize_t, "pwrite64",
2956 unsigned int, fd, const char *, buf, vki_size_t, count,
2957 Word, offset);
2958 #else
2959 # error Unexpected word size
2960 #endif
2961 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
2963 #endif
2965 PRE(sys_sync)
2967 *flags |= SfMayBlock;
2968 PRINT("sys_sync ( )");
2969 PRE_REG_READ0(long, "sync");
2972 #if !defined(VGP_nanomips_linux)
2973 PRE(sys_fstatfs)
2975 FUSE_COMPATIBLE_MAY_BLOCK();
2976 PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
2977 PRE_REG_READ2(long, "fstatfs",
2978 unsigned int, fd, struct statfs *, buf);
2979 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
2982 POST(sys_fstatfs)
2984 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
2987 PRE(sys_fstatfs64)
2989 FUSE_COMPATIBLE_MAY_BLOCK();
2990 PRINT("sys_fstatfs64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
2991 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
2992 PRE_REG_READ3(long, "fstatfs64",
2993 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
2994 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
2996 POST(sys_fstatfs64)
2998 POST_MEM_WRITE( ARG3, ARG2 );
3000 #endif
3002 PRE(sys_getsid)
3004 PRINT("sys_getsid ( %ld )", SARG1);
3005 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
3008 #if !defined(VGO_freebsd)
3009 PRE(sys_pread64)
3011 *flags |= SfMayBlock;
3012 #if VG_WORDSIZE == 4
3013 PRINT("sys_pread64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3014 FMT_REGWORD "u, %lld )", ARG1, ARG2, ARG3, (Long)MERGE64(ARG4,ARG5));
3015 PRE_REG_READ5(ssize_t, "pread64",
3016 unsigned int, fd, char *, buf, vki_size_t, count,
3017 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
3018 #elif VG_WORDSIZE == 8
3019 PRINT("sys_pread64 ( %lu, %#lx, %lu, %ld )",
3020 ARG1, ARG2, ARG3, SARG4);
3021 PRE_REG_READ4(ssize_t, "pread64",
3022 unsigned int, fd, char *, buf, vki_size_t, count,
3023 Word, offset);
3024 #else
3025 # error Unexpected word size
3026 #endif
3027 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
3029 POST(sys_pread64)
3031 vg_assert(SUCCESS);
3032 if (RES > 0) {
3033 POST_MEM_WRITE( ARG2, RES );
3036 #endif
3038 PRE(sys_mknod)
3040 FUSE_COMPATIBLE_MAY_BLOCK();
3041 PRINT("sys_mknod ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#"
3042 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, ARG2, ARG3 );
3043 PRE_REG_READ3(long, "mknod",
3044 const char *, pathname, int, mode, unsigned, dev);
3045 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
3048 PRE(sys_flock)
3050 *flags |= SfMayBlock;
3051 PRINT("sys_flock ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2 );
3052 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
3055 // Pre_read a char** argument.
3056 void ML_(pre_argv_envp)(Addr a, ThreadId tid, const HChar *s1, const HChar *s2)
3058 while (True) {
3059 Addr a_deref;
3060 Addr* a_p = (Addr*)a;
3061 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
3062 a_deref = *a_p;
3063 if (0 == a_deref)
3064 break;
3065 PRE_MEM_RASCIIZ( s2, a_deref );
3066 a += sizeof(char*);
3070 static Bool i_am_the_only_thread ( void )
3072 Int c = VG_(count_living_threads)();
3073 vg_assert(c >= 1); /* stay sane */
3074 return c == 1;
3077 /* Wait until all other threads disappear. */
3078 void VG_(reap_threads)(ThreadId self)
3080 while (!i_am_the_only_thread()) {
3081 /* Let other thread(s) run */
3082 VG_(vg_yield)();
3083 VG_(poll_signals)(self);
3085 vg_assert(i_am_the_only_thread());
3088 /* This handles the common part of the PRE macro for execve and execveat. */
3089 void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname,
3090 Addr arg_2, Addr arg_3, ExecveType execveType,
3091 Bool check_pathptr)
3093 HChar* path = NULL; /* path to executable */
3094 HChar** envp = NULL;
3095 HChar** argv = NULL;
3096 HChar** arg2copy;
3097 HChar* launcher_basename = NULL;
3098 ThreadState* tst;
3099 Int i, j, tot_args;
3100 SysRes res;
3101 Bool setuid_allowed, trace_this_child;
3102 const char *str;
3103 char str2[30], str3[30];
3104 Addr arg_2_check = arg_2;
3106 switch (execveType) {
3107 case EXECVE:
3108 str = "execve";
3109 break;
3110 case EXECVEAT:
3111 str = "execveat";
3112 break;
3113 case FEXECVE:
3114 str = "fexecve";
3115 break;
3116 default:
3117 vg_assert(False);
3120 VG_(strcpy)(str2, str);
3121 VG_(strcpy)(str3, str);
3123 VG_(strcat)(str2, "(argv)");
3124 VG_(strcat)(str3, "(argv[0])");
3126 /* argv[] should not be NULL and valid. */
3127 PRE_MEM_READ(str2, arg_2_check, sizeof(Addr));
3129 /* argv[0] should not be NULL and valid. */
3130 if (ML_(safe_to_deref)((HChar **) (Addr)arg_2_check, sizeof(HChar *))) {
3131 Addr argv0 = *(Addr*)arg_2_check;
3132 PRE_MEM_RASCIIZ( str3, argv0 );
3133 /* The rest of argv can be NULL or a valid string pointer. */
3134 if (VG_(am_is_valid_for_client)(arg_2_check, sizeof(HChar), VKI_PROT_READ)) {
3135 arg_2_check += sizeof(HChar*);
3136 str3[VG_(strlen)(str)] = '\0';
3137 VG_(strcat)(str3, "(argv[i])");
3138 ML_(pre_argv_envp)( arg_2_check, tid, str2, str3 );
3140 } else {
3141 SET_STATUS_Failure(VKI_EFAULT);
3142 return;
3144 // Reset helper strings to syscall name.
3145 str2[VG_(strlen)(str)] = '\0';
3146 str3[VG_(strlen)(str)] = '\0';
3147 if (arg_3 != 0) {
3148 /* At least the terminating NULL must be addressable. */
3149 if (!ML_(safe_to_deref)((HChar **) (Addr)arg_3, sizeof(HChar *))) {
3150 SET_STATUS_Failure(VKI_EFAULT);
3151 return;
3153 VG_(strcat)(str2, "(envp)");
3154 VG_(strcat)(str3, "(envp[i])");
3155 ML_(pre_argv_envp)( arg_3, tid, str2, str3 );
3158 vg_assert(VG_(is_valid_tid)(tid));
3159 tst = VG_(get_ThreadState)(tid);
3161 /* Erk. If the exec fails, then the following will have made a
3162 mess of things which makes it hard for us to continue. The
3163 right thing to do is piece everything together again in
3164 POST(execve), but that's close to impossible. Instead, we make
3165 an effort to check that the execve will work before actually
3166 doing it. */
3168 /* Check that the name at least begins in client-accessible storage.
3169 If we didn't create it ourselves in execveat. */
3170 if (check_pathptr
3171 && !VG_(am_is_valid_for_client)( pathname, 1, VKI_PROT_READ )) {
3172 SET_STATUS_Failure( VKI_EFAULT );
3173 return;
3176 // debug-only printing
3177 if (0) {
3178 VG_(printf)("pathname = %p(%s)\n", (void*)(Addr)pathname, (HChar*)(Addr)pathname);
3179 if (arg_2) {
3180 VG_(printf)("arg_2 = ");
3181 Int q;
3182 HChar** vec = (HChar**)(Addr)arg_2;
3183 for (q = 0; vec[q]; q++)
3184 VG_(printf)("%p(%s) ", vec[q], vec[q]);
3185 VG_(printf)("\n");
3186 } else {
3187 VG_(printf)("arg_2 = null\n");
3191 // Decide whether or not we want to follow along
3192 { // Make 'child_argv' be a pointer to the child's arg vector
3193 // (skipping the exe name)
3194 const HChar** child_argv = (const HChar**)(Addr)arg_2;
3195 if (child_argv && child_argv[0] == NULL)
3196 child_argv = NULL;
3197 trace_this_child = VG_(should_we_trace_this_child)( (HChar*)(Addr)pathname,
3198 child_argv );
3201 // Do the important checks: it is a file, is executable, permissions are
3202 // ok, etc. We allow setuid executables to run only in the case when
3203 // we are not simulating them, that is, they to be run natively.
3204 setuid_allowed = trace_this_child ? False : True;
3205 res = VG_(pre_exec_check)((const HChar *)(Addr)pathname, NULL, setuid_allowed);
3206 if (sr_isError(res)) {
3207 SET_STATUS_Failure( sr_Err(res) );
3208 return;
3211 /* If we're tracing the child, and the launcher name looks bogus
3212 (possibly because launcher.c couldn't figure it out, see
3213 comments therein) then we have no option but to fail. */
3214 if (trace_this_child
3215 && (VG_(name_of_launcher) == NULL
3216 || VG_(name_of_launcher)[0] != '/')) {
3217 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
3218 return;
3221 /* After this point, we can't recover if the execve fails. */
3222 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)(Addr)pathname);
3225 // Terminate gdbserver if it is active.
3226 if (VG_(clo_vgdb) != Vg_VgdbNo) {
3227 // If the child will not be traced, we need to terminate gdbserver
3228 // to cleanup the gdbserver resources (e.g. the FIFO files).
3229 // If child will be traced, we also terminate gdbserver: the new
3230 // Valgrind will start a fresh gdbserver after exec.
3231 VG_(gdbserver) (0);
3234 /* Resistance is futile. Nuke all other threads. POSIX mandates
3235 this. (Really, nuke them all, since the new process will make
3236 its own new thread.) */
3237 VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
3238 VG_(reap_threads)(tid);
3240 // Set up the child's exe path.
3242 if (trace_this_child) {
3244 // We want to exec the launcher. Get its pre-remembered path.
3245 path = VG_(name_of_launcher);
3246 // VG_(name_of_launcher) should have been acquired by m_main at
3247 // startup.
3248 vg_assert(path);
3250 launcher_basename = VG_(strrchr)(path, '/');
3251 if (launcher_basename == NULL || launcher_basename[1] == 0) {
3252 launcher_basename = path; // hmm, tres dubious
3253 } else {
3254 launcher_basename++;
3257 } else {
3258 path = (HChar*)(Addr)pathname;
3261 // Set up the child's environment.
3263 // Remove the valgrind-specific stuff from the environment so the
3264 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
3265 // This is done unconditionally, since if we are tracing the child,
3266 // the child valgrind will set up the appropriate client environment.
3267 // Nb: we make a copy of the environment before trying to mangle it
3268 // as it might be in read-only memory (this was bug #101881).
3270 // Then, if tracing the child, set VALGRIND_LIB for it.
3272 if (arg_3 == 0) {
3273 envp = NULL;
3274 } else {
3275 envp = VG_(env_clone)( (HChar**)(Addr)arg_3 );
3276 if (envp == NULL) goto hosed;
3277 VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL );
3280 if (trace_this_child) {
3281 // Set VALGRIND_LIB in arg_3 (the environment)
3282 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
3285 // Set up the child's args. If not tracing it, they are
3286 // simply arg_2. Otherwise, they are
3288 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [pathname] ++ arg_2[1..]
3290 // except that the first VG_(args_for_valgrind_noexecpass) args
3291 // are omitted.
3293 if (!trace_this_child) {
3294 argv = (HChar**)(Addr)arg_2;
3295 } else {
3296 vg_assert( VG_(args_for_valgrind) );
3297 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
3298 vg_assert( VG_(args_for_valgrind_noexecpass)
3299 <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
3300 /* how many args in total will there be? */
3301 // launcher basename
3302 tot_args = 1;
3303 // V's args
3304 tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
3305 tot_args -= VG_(args_for_valgrind_noexecpass);
3306 // name of client exe
3307 tot_args++;
3308 // args for client exe, skipping [0]
3309 arg2copy = (HChar**)(Addr)arg_2;
3310 if (arg2copy && arg2copy[0]) {
3311 for (i = 1; arg2copy[i]; i++)
3312 tot_args++;
3314 // allocate
3315 argv = VG_(malloc)( "di.syswrap.pre_sys_execve.1",
3316 (tot_args+1) * sizeof(HChar*) );
3317 // copy
3318 j = 0;
3319 argv[j++] = launcher_basename;
3320 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
3321 if (i < VG_(args_for_valgrind_noexecpass))
3322 continue;
3323 argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
3325 argv[j++] = (HChar*)(Addr)pathname;
3326 if (arg2copy && arg2copy[0])
3327 for (i = 1; arg2copy[i]; i++)
3328 argv[j++] = arg2copy[i];
3329 argv[j++] = NULL;
3330 // check
3331 vg_assert(j == tot_args+1);
3335 Set the signal state up for exec.
3337 We need to set the real signal state to make sure the exec'd
3338 process gets SIG_IGN properly.
3340 Also set our real sigmask to match the client's sigmask so that
3341 the exec'd child will get the right mask. First we need to
3342 clear out any pending signals so they they don't get delivered,
3343 which would confuse things.
3345 XXX This is a bug - the signals should remain pending, and be
3346 delivered to the new process after exec. There's also a
3347 race-condition, since if someone delivers us a signal between
3348 the sigprocmask and the execve, we'll still get the signal. Oh
3349 well.
3352 vki_sigset_t allsigs;
3353 vki_siginfo_t info;
3355 /* What this loop does: it queries SCSS (the signal state that
3356 the client _thinks_ the kernel is in) by calling
3357 VG_(do_sys_sigaction), and modifies the real kernel signal
3358 state accordingly. */
3359 for (i = 1; i < VG_(max_signal); i++) {
3360 vki_sigaction_fromK_t sa_f;
3361 vki_sigaction_toK_t sa_t;
3362 VG_(do_sys_sigaction)(i, NULL, &sa_f);
3363 VG_(convert_sigaction_fromK_to_toK)(&sa_f, &sa_t);
3364 if (sa_t.ksa_handler == VKI_SIG_IGN)
3365 VG_(sigaction)(i, &sa_t, NULL);
3366 else {
3367 sa_t.ksa_handler = VKI_SIG_DFL;
3368 VG_(sigaction)(i, &sa_t, NULL);
3372 VG_(sigfillset)(&allsigs);
3373 while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
3376 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
3379 if (0) {
3380 HChar **cpp;
3381 VG_(printf)("exec: %s\n", path);
3382 for (cpp = argv; cpp && *cpp; cpp++)
3383 VG_(printf)("argv: %s\n", *cpp);
3384 if (0)
3385 for (cpp = envp; cpp && *cpp; cpp++)
3386 VG_(printf)("env: %s\n", *cpp);
3389 // always execute this because it's executing valgrind, not the "target" exe
3390 SET_STATUS_from_SysRes(
3391 VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp));
3393 /* If we got here, then the execve failed. We've already made way
3394 too much of a mess to continue, so we have to abort. */
3395 hosed:
3396 vg_assert(FAILURE);
3397 VG_(message)(Vg_UserMsg, "execve(%#" FMT_REGWORD "x(%s), %#" FMT_REGWORD
3398 "x, %#" FMT_REGWORD "x) failed, errno %lu\n",
3399 pathname, (HChar*)(Addr)pathname, arg_2, arg_3, ERR);
3400 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
3401 "execve() failing, so I'm dying.\n");
3402 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
3403 "or work out how to recover.\n");
3404 VG_(exit)(101);
3408 // XXX: prototype here seemingly doesn't match the prototype for i386-linux,
3409 // but it seems to work nonetheless...
3410 PRE(sys_execve)
3412 PRINT("sys_execve ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#"
3413 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, ARG2, ARG3);
3414 PRE_REG_READ3(vki_off_t, "execve",
3415 char *, filename, char **, argv, char **, envp);
3416 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
3418 char *pathname = (char *)ARG1;
3419 Addr arg_2 = (Addr)ARG2;
3420 Addr arg_3 = (Addr)ARG3;
3422 handle_pre_sys_execve(tid, status, (Addr)pathname, arg_2, arg_3, EXECVE, True);
3425 PRE(sys_access)
3427 PRINT("sys_access ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
3428 (HChar*)(Addr)ARG1, SARG2);
3429 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
3430 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
3433 PRE(sys_alarm)
3435 PRINT("sys_alarm ( %" FMT_REGWORD "u )", ARG1);
3436 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
3439 PRE(sys_brk)
3441 Addr brk_limit = VG_(brk_limit);
3442 Addr brk_new;
3444 /* libc says: int brk(void *end_data_segment);
3445 kernel says: void* brk(void* end_data_segment); (more or less)
3447 libc returns 0 on success, and -1 (and sets errno) on failure.
3448 Nb: if you ask to shrink the dataseg end below what it
3449 currently is, that always succeeds, even if the dataseg end
3450 doesn't actually change (eg. brk(0)). Unless it seg faults.
3452 Kernel returns the new dataseg end. If the brk() failed, this
3453 will be unchanged from the old one. That's why calling (kernel)
3454 brk(0) gives the current dataseg end (libc brk() just returns
3455 zero in that case).
3457 Both will seg fault if you shrink it back into a text segment.
3459 PRINT("sys_brk ( %#" FMT_REGWORD "x )", ARG1);
3460 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
3462 brk_new = do_brk(ARG1, tid);
3463 SET_STATUS_Success( brk_new );
3465 if (brk_new == ARG1) {
3466 /* brk() succeeded */
3467 if (brk_new < brk_limit) {
3468 /* successfully shrunk the data segment. */
3469 VG_TRACK( die_mem_brk, (Addr)ARG1,
3470 brk_limit-ARG1 );
3471 } else
3472 if (brk_new > brk_limit) {
3473 /* successfully grew the data segment */
3474 VG_TRACK( new_mem_brk, brk_limit,
3475 ARG1-brk_limit, tid );
3477 } else {
3478 /* brk() failed */
3479 vg_assert(brk_limit == brk_new);
3483 PRE(sys_chdir)
3485 FUSE_COMPATIBLE_MAY_BLOCK();
3486 PRINT("sys_chdir ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
3487 PRE_REG_READ1(long, "chdir", const char *, path);
3488 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
3491 PRE(sys_chmod)
3493 FUSE_COMPATIBLE_MAY_BLOCK();
3494 PRINT("sys_chmod ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,
3495 (HChar*)(Addr)ARG1, ARG2);
3496 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
3497 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
3500 PRE(sys_chown)
3502 FUSE_COMPATIBLE_MAY_BLOCK();
3503 PRINT("sys_chown ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
3504 FMT_REGWORD "x )", ARG1,(char*)(Addr)ARG1,ARG2,ARG3);
3505 PRE_REG_READ3(long, "chown",
3506 const char *, path, vki_uid_t, owner, vki_gid_t, group);
3507 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
3510 PRE(sys_lchown)
3512 FUSE_COMPATIBLE_MAY_BLOCK();
3513 PRINT("sys_lchown ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
3514 FMT_REGWORD "x )", ARG1,(char*)(Addr)ARG1,ARG2,ARG3);
3515 PRE_REG_READ3(long, "lchown",
3516 const char *, path, vki_uid_t, owner, vki_gid_t, group);
3517 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
3520 PRE(sys_close)
3522 FUSE_COMPATIBLE_MAY_BLOCK();
3523 PRINT("sys_close ( %" FMT_REGWORD "u )", ARG1);
3524 PRE_REG_READ1(long, "close", unsigned int, fd);
3526 /* Detect and negate attempts by the client to close Valgrind's log fd */
3527 if ( (!ML_(fd_allowed)(ARG1, "close", tid, False))
3528 /* If doing -d style logging (which is to fd=2), don't
3529 allow that to be closed either. */
3530 || (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0) )
3531 SET_STATUS_Failure( VKI_EBADF );
3532 else {
3533 /* We used to do close tracking in the POST handler, but that is
3534 only called on success. Even if the close syscall fails the
3535 file descriptor is still really closed/invalid. So we do the
3536 recording and checking here. */
3537 if (VG_(clo_track_fds)) ML_(record_fd_close)(tid, ARG1);
3541 PRE(sys_dup)
3543 PRINT("sys_dup ( %" FMT_REGWORD "u )", ARG1);
3544 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
3547 POST(sys_dup)
3549 vg_assert(SUCCESS);
3550 if (!ML_(fd_allowed)(RES, "dup", tid, True)) {
3551 VG_(close)(RES);
3552 SET_STATUS_Failure( VKI_EMFILE );
3553 } else {
3554 if (VG_(clo_track_fds))
3555 ML_(record_fd_open_named)(tid, RES);
3559 PRE(sys_dup2)
3561 PRINT("sys_dup2 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3562 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
3563 if (!ML_(fd_allowed)(ARG2, "dup2", tid, True))
3564 SET_STATUS_Failure( VKI_EBADF );
3567 POST(sys_dup2)
3569 vg_assert(SUCCESS);
3570 if (VG_(clo_track_fds))
3571 ML_(record_fd_open_named)(tid, RES);
3574 PRE(sys_fchdir)
3576 FUSE_COMPATIBLE_MAY_BLOCK();
3577 PRINT("sys_fchdir ( %" FMT_REGWORD "u )", ARG1);
3578 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
3581 PRE(sys_fchown)
3583 FUSE_COMPATIBLE_MAY_BLOCK();
3584 PRINT("sys_fchown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3585 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3586 PRE_REG_READ3(long, "fchown",
3587 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
3590 PRE(sys_fchmod)
3592 FUSE_COMPATIBLE_MAY_BLOCK();
3593 PRINT("sys_fchmod ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3594 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
3597 #if !defined(VGP_nanomips_linux) && !defined (VGO_freebsd)
3598 PRE(sys_newfstat)
3600 FUSE_COMPATIBLE_MAY_BLOCK();
3601 PRINT("sys_newfstat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3602 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
3603 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
3606 POST(sys_newfstat)
3608 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
3610 #endif
3612 #if !defined(VGO_solaris) && !defined(VGP_arm64_linux) && \
3613 !defined(VGP_nanomips_linux)
3614 static vki_sigset_t fork_saved_mask;
3616 // In Linux, the sys_fork() function varies across architectures, but we
3617 // ignore the various args it gets, and so it looks arch-neutral. Hmm.
3618 PRE(sys_fork)
3620 Bool is_child;
3621 Int child_pid;
3622 vki_sigset_t mask;
3624 PRINT("sys_fork ( )");
3625 PRE_REG_READ0(long, "fork");
3627 /* Block all signals during fork, so that we can fix things up in
3628 the child without being interrupted. */
3629 VG_(sigfillset)(&mask);
3630 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
3632 VG_(do_atfork_pre)(tid);
3634 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
3636 if (!SUCCESS) return;
3638 #if defined(VGO_linux) || defined(VGO_freebsd)
3639 // RES is 0 for child, non-0 (the child's PID) for parent.
3640 is_child = ( RES == 0 ? True : False );
3641 child_pid = ( is_child ? -1 : RES );
3642 #elif defined(VGO_darwin)
3643 // RES is the child's pid. RESHI is 1 for child, 0 for parent.
3644 is_child = RESHI;
3645 child_pid = RES;
3646 #else
3647 # error Unknown OS
3648 #endif
3650 if (is_child) {
3651 VG_(do_atfork_child)(tid);
3653 /* restore signal mask */
3654 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
3655 } else {
3656 VG_(do_atfork_parent)(tid);
3658 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), child_pid);
3660 /* restore signal mask */
3661 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
3664 #endif // !defined(VGO_solaris) && !defined(VGP_arm64_linux)
3666 PRE(sys_ftruncate)
3668 *flags |= SfMayBlock;
3669 PRINT("sys_ftruncate ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3670 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
3673 PRE(sys_truncate)
3675 *flags |= SfMayBlock;
3676 PRINT("sys_truncate ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
3677 ARG1, (HChar*)(Addr)ARG1, ARG2);
3678 PRE_REG_READ2(long, "truncate",
3679 const char *, path, unsigned long, length);
3680 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
3683 PRE(sys_ftruncate64)
3685 *flags |= SfMayBlock;
3686 #if VG_WORDSIZE == 4
3687 PRINT("sys_ftruncate64 ( %" FMT_REGWORD "u, %llu )", ARG1,
3688 MERGE64(ARG2,ARG3));
3689 PRE_REG_READ3(long, "ftruncate64",
3690 unsigned int, fd,
3691 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
3692 #else
3693 PRINT("sys_ftruncate64 ( %lu, %lu )", ARG1, ARG2);
3694 PRE_REG_READ2(long, "ftruncate64",
3695 unsigned int,fd, UWord,length);
3696 #endif
3699 PRE(sys_truncate64)
3701 *flags |= SfMayBlock;
3702 #if VG_WORDSIZE == 4
3703 PRINT("sys_truncate64 ( %#" FMT_REGWORD "x, %lld )", ARG1,
3704 (Long)MERGE64(ARG2, ARG3));
3705 PRE_REG_READ3(long, "truncate64",
3706 const char *, path,
3707 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
3708 #else
3709 PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)ARG2);
3710 PRE_REG_READ2(long, "truncate64",
3711 const char *,path, UWord,length);
3712 #endif
3713 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
3716 PRE(sys_getdents)
3718 *flags |= SfMayBlock;
3719 PRINT("sys_getdents ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
3720 "u )", ARG1, ARG2, ARG3);
3721 PRE_REG_READ3(long, "getdents",
3722 unsigned int, fd, struct vki_dirent *, dirp,
3723 unsigned int, count);
3724 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
3727 POST(sys_getdents)
3729 vg_assert(SUCCESS);
3730 if (RES > 0)
3731 POST_MEM_WRITE( ARG2, RES );
3734 PRE(sys_getdents64)
3736 *flags |= SfMayBlock;
3737 PRINT("sys_getdents64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3738 FMT_REGWORD "u )",ARG1, ARG2, ARG3);
3739 PRE_REG_READ3(long, "getdents64",
3740 unsigned int, fd, struct vki_dirent64 *, dirp,
3741 unsigned int, count);
3742 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
3745 POST(sys_getdents64)
3747 vg_assert(SUCCESS);
3748 if (RES > 0)
3749 POST_MEM_WRITE( ARG2, RES );
3752 PRE(sys_getgroups)
3754 PRINT("sys_getgroups ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3755 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
3756 if (ARG1 > 0)
3757 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
3760 POST(sys_getgroups)
3762 vg_assert(SUCCESS);
3763 if (ARG1 > 0 && RES > 0)
3764 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
3767 PRE(sys_getcwd)
3769 // Comment from linux/fs/dcache.c:
3770 // NOTE! The user-level library version returns a character pointer.
3771 // The kernel system call just returns the length of the buffer filled
3772 // (which includes the ending '\0' character), or a negative error
3773 // value.
3774 // Is this Linux-specific? If so it should be moved to syswrap-linux.c.
3775 PRINT("sys_getcwd ( %#" FMT_REGWORD "x, %llu )", ARG1,(ULong)ARG2);
3776 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
3777 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
3780 POST(sys_getcwd)
3782 vg_assert(SUCCESS);
3783 if (RES != (Addr)NULL)
3784 POST_MEM_WRITE( ARG1, RES );
3787 PRE(sys_geteuid)
3789 PRINT("sys_geteuid ( )");
3790 PRE_REG_READ0(long, "geteuid");
3793 PRE(sys_getegid)
3795 PRINT("sys_getegid ( )");
3796 PRE_REG_READ0(long, "getegid");
3799 PRE(sys_getgid)
3801 PRINT("sys_getgid ( )");
3802 PRE_REG_READ0(long, "getgid");
3805 PRE(sys_getpid)
3807 PRINT("sys_getpid ()");
3808 PRE_REG_READ0(long, "getpid");
3811 PRE(sys_getpgid)
3813 PRINT("sys_getpgid ( %ld )", SARG1);
3814 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
3817 PRE(sys_getpgrp)
3819 PRINT("sys_getpgrp ()");
3820 PRE_REG_READ0(long, "getpgrp");
3823 PRE(sys_getppid)
3825 PRINT("sys_getppid ()");
3826 PRE_REG_READ0(long, "getppid");
3829 static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
3831 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
3833 #ifdef _RLIMIT_POSIX_FLAG
3834 // Darwin will sometimes set _RLIMIT_POSIX_FLAG on getrlimit calls.
3835 // Unset it here to make the switch case below work correctly.
3836 a1 &= ~_RLIMIT_POSIX_FLAG;
3837 #endif
3839 switch (a1) {
3840 case VKI_RLIMIT_NOFILE:
3841 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
3842 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
3843 break;
3845 case VKI_RLIMIT_DATA:
3846 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
3847 break;
3849 case VKI_RLIMIT_STACK:
3850 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
3851 break;
3855 PRE(sys_old_getrlimit)
3857 PRINT("sys_old_getrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3858 ARG1, ARG2);
3859 PRE_REG_READ2(long, "old_getrlimit",
3860 unsigned int, resource, struct rlimit *, rlim);
3861 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
3864 POST(sys_old_getrlimit)
3866 common_post_getrlimit(tid, ARG1, ARG2);
3869 PRE(sys_getrlimit)
3871 PRINT("sys_getrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3872 PRE_REG_READ2(long, "getrlimit",
3873 unsigned int, resource, struct rlimit *, rlim);
3874 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
3877 POST(sys_getrlimit)
3879 common_post_getrlimit(tid, ARG1, ARG2);
3882 PRE(sys_getrusage)
3884 PRINT("sys_getrusage ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3885 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
3886 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
3889 POST(sys_getrusage)
3891 vg_assert(SUCCESS);
3892 if (RES == 0)
3893 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
3896 PRE(sys_gettimeofday)
3898 PRINT("sys_gettimeofday ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3899 ARG1,ARG2);
3900 PRE_REG_READ2(long, "gettimeofday",
3901 struct timeval *, tv, struct timezone *, tz);
3902 // GrP fixme does darwin write to *tz anymore?
3903 if (ARG1 != 0)
3904 PRE_timeval_WRITE( "gettimeofday(tv)", (Addr)ARG1 );
3905 if (ARG2 != 0)
3906 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3909 POST(sys_gettimeofday)
3911 vg_assert(SUCCESS);
3912 if (RES == 0) {
3913 if (ARG1 != 0)
3914 POST_timeval_WRITE( (Addr)ARG1 );
3915 if (ARG2 != 0)
3916 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
3920 PRE(sys_settimeofday)
3922 PRINT("sys_settimeofday ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3923 ARG1,ARG2);
3924 PRE_REG_READ2(long, "settimeofday",
3925 struct timeval *, tv, struct timezone *, tz);
3926 if (ARG1 != 0)
3927 PRE_timeval_READ( "settimeofday(tv)", (Addr)ARG1 );
3928 if (ARG2 != 0) {
3929 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3930 /* maybe should warn if tz->tz_dsttime is non-zero? */
3934 PRE(sys_getuid)
3936 PRINT("sys_getuid ( )");
3937 PRE_REG_READ0(long, "getuid");
3940 void ML_(PRE_unknown_ioctl)(ThreadId tid, UWord request, UWord arg)
3942 /* We don't have any specific information on it, so
3943 try to do something reasonable based on direction and
3944 size bits. The encoding scheme is described in
3945 /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h .
3947 According to Simon Hausmann, _IOC_READ means the kernel
3948 writes a value to the ioctl value passed from the user
3949 space and the other way around with _IOC_WRITE. */
3951 #if defined(VGO_solaris)
3952 /* Majority of Solaris ioctl requests does not honour direction hints. */
3953 UInt dir = _VKI_IOC_NONE;
3954 #else
3955 UInt dir = _VKI_IOC_DIR(request);
3956 #endif
3957 UInt size = _VKI_IOC_SIZE(request);
3959 if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) {
3961 * Be very lax about ioctl handling; the only
3962 * assumption is that the size is correct. Doesn't
3963 * require the full buffer to be initialized when
3964 * writing. Without this, using some device
3965 * drivers with a large number of strange ioctl
3966 * commands becomes very tiresome.
3968 } else if (dir == _VKI_IOC_NONE && size > 0) {
3969 static UWord unknown_ioctl[10];
3970 static Int moans = sizeof(unknown_ioctl) / sizeof(unknown_ioctl[0]);
3972 if (moans > 0 && !VG_(clo_xml)) {
3973 /* Check if have not already moaned for this request. */
3974 UInt i;
3975 for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) {
3976 if (unknown_ioctl[i] == request)
3977 break;
3978 if (unknown_ioctl[i] == 0) {
3979 unknown_ioctl[i] = request;
3980 moans--;
3981 VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx"
3982 " with no direction hints.\n", request);
3983 VG_(umsg)(" This could cause spurious value errors to appear.\n");
3984 VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for "
3985 "guidance on writing a proper wrapper.\n" );
3986 //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
3987 return;
3991 } else {
3992 //VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request);
3993 //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
3994 if ((dir & _VKI_IOC_WRITE) && size > 0)
3995 PRE_MEM_READ( "ioctl(generic)", arg, size);
3996 if ((dir & _VKI_IOC_READ) && size > 0)
3997 PRE_MEM_WRITE( "ioctl(generic)", arg, size);
4001 void ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg)
4003 /* We don't have any specific information on it, so
4004 try to do something reasonable based on direction and
4005 size bits. The encoding scheme is described in
4006 /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h .
4008 According to Simon Hausmann, _IOC_READ means the kernel
4009 writes a value to the ioctl value passed from the user
4010 space and the other way around with _IOC_WRITE. */
4012 UInt dir = _VKI_IOC_DIR(request);
4013 UInt size = _VKI_IOC_SIZE(request);
4014 if (size > 0 && (dir & _VKI_IOC_READ)
4015 && res == 0
4016 && arg != (Addr)NULL) {
4017 POST_MEM_WRITE(arg, size);
4022 If we're sending a SIGKILL to one of our own threads, then simulate
4023 it rather than really sending the signal, so that the target thread
4024 gets a chance to clean up. Returns True if we did the killing (or
4025 no killing is necessary), and False if the caller should use the
4026 normal kill syscall.
4028 "pid" is any pid argument which can be passed to kill; group kills
4029 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4030 they'll most likely hit all the threads and we won't need to worry
4031 about cleanup. In truth, we can't fully emulate these multicast
4032 kills.
4034 "tgid" is a thread group id. If it is not -1, then the target
4035 thread must be in that thread group.
4037 Bool ML_(do_sigkill)(Int pid, Int tgid)
4039 ThreadState *tst;
4040 ThreadId tid;
4042 if (pid <= 0)
4043 return False;
4045 tid = VG_(lwpid_to_vgtid)(pid);
4046 if (tid == VG_INVALID_THREADID)
4047 return False; /* none of our threads */
4049 tst = VG_(get_ThreadState)(tid);
4050 if (tst == NULL || tst->status == VgTs_Empty)
4051 return False; /* hm, shouldn't happen */
4053 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4054 return False; /* not the right thread group */
4056 /* Fatal SIGKILL sent to one of our threads.
4057 "Handle" the signal ourselves, as trying to have tid
4058 handling the signal causes termination problems (see #409367
4059 and #409141).
4060 Moreover, as a process cannot do anything when receiving SIGKILL,
4061 it is not particularly crucial that "tid" does the work to
4062 terminate the process. */
4064 if (VG_(clo_trace_signals))
4065 VG_(message)(Vg_DebugMsg,
4066 "Thread %u %s being killed with SIGKILL, running tid: %u\n",
4067 tst->tid, VG_(name_of_ThreadStatus) (tst->status), VG_(running_tid));
4069 if (!VG_(is_running_thread)(tid))
4070 tst = VG_(get_ThreadState)(VG_(running_tid));
4071 VG_(nuke_all_threads_except) (VG_(running_tid), VgSrc_FatalSig);
4072 VG_(reap_threads)(VG_(running_tid));
4073 tst->exitreason = VgSrc_FatalSig;
4074 tst->os_state.fatalsig = VKI_SIGKILL;
4076 return True;
4079 PRE(sys_kill)
4081 PRINT("sys_kill ( %ld, %ld )", SARG1, SARG2);
4082 PRE_REG_READ2(long, "kill", int, pid, int, signal);
4083 if (!ML_(client_signal_OK)(ARG2)) {
4084 SET_STATUS_Failure( VKI_EINVAL );
4085 return;
4088 /* If we're sending SIGKILL, check to see if the target is one of
4089 our threads and handle it specially. */
4090 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
4091 SET_STATUS_Success(0);
4092 else
4093 /* re syscall3: Darwin has a 3rd arg, which is a flag (boolean)
4094 affecting how posix-compliant the call is. I guess it is
4095 harmless to pass the 3rd arg on other platforms; hence pass
4096 it on all. */
4097 SET_STATUS_from_SysRes( VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3) );
4099 if (VG_(clo_trace_signals))
4100 VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld\n",
4101 SARG2, SARG1);
4103 /* This kill might have given us a pending signal. Ask for a check once
4104 the syscall is done. */
4105 *flags |= SfPollAfter;
4108 PRE(sys_link)
4110 *flags |= SfMayBlock;
4111 PRINT("sys_link ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )", ARG1,
4112 (char*)(Addr)ARG1,ARG2,(char*)(Addr)ARG2);
4113 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
4114 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4115 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
4118 #if !defined(VGP_nanomips_linux) && !defined(VGO_freebsd)
4119 PRE(sys_newlstat)
4121 PRINT("sys_newlstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,
4122 (char*)(Addr)ARG1,ARG2);
4123 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
4124 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4125 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
4128 POST(sys_newlstat)
4130 vg_assert(SUCCESS);
4131 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4133 #endif
4135 PRE(sys_mkdir)
4137 *flags |= SfMayBlock;
4138 PRINT("sys_mkdir ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
4139 (HChar*)(Addr)ARG1, SARG2);
4140 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
4141 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
4144 PRE(sys_mprotect)
4146 PRINT("sys_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4147 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4148 PRE_REG_READ3(long, "mprotect",
4149 unsigned long, addr, vki_size_t, len, unsigned long, prot);
4151 Addr addr = ARG1;
4152 SizeT len = ARG2;
4153 Int prot = ARG3;
4155 handle_sys_mprotect (tid, status, &addr, &len, &prot);
4157 ARG1 = addr;
4158 ARG2 = len;
4159 ARG3 = prot;
4161 /* This will be called from the generic mprotect, or the linux specific
4162 pkey_mprotect. Pass pointers to ARG1, ARG2 and ARG3 as addr, len and prot,
4163 they might be adjusted and have to assigned back to ARG1, ARG2 and ARG3. */
4164 void handle_sys_mprotect(ThreadId tid, SyscallStatus* status,
4165 Addr *addr, SizeT *len, Int *prot)
4167 if (!ML_(valid_client_addr)(*addr, *len, tid, "mprotect")) {
4168 #if defined(VGO_freebsd)
4169 SET_STATUS_Failure( VKI_EINVAL );
4170 #else
4171 SET_STATUS_Failure( VKI_ENOMEM );
4172 #endif
4174 #if defined(VKI_PROT_GROWSDOWN)
4175 else
4176 if (*prot & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
4177 /* Deal with mprotects on growable stack areas.
4179 The critical files to understand all this are mm/mprotect.c
4180 in the kernel and sysdeps/unix/sysv/linux/dl-execstack.c in
4181 glibc.
4183 The kernel provides PROT_GROWSDOWN and PROT_GROWSUP which
4184 round the start/end address of mprotect to the start/end of
4185 the underlying vma and glibc uses that as an easy way to
4186 change the protection of the stack by calling mprotect on the
4187 last page of the stack with PROT_GROWSDOWN set.
4189 The sanity check provided by the kernel is that the vma must
4190 have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate. */
4191 UInt grows = *prot & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
4192 NSegment const *aseg = VG_(am_find_nsegment)(*addr);
4193 NSegment const *rseg;
4195 vg_assert(aseg);
4197 if (grows == VKI_PROT_GROWSDOWN) {
4198 rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ );
4199 if (rseg
4200 && rseg->kind == SkResvn
4201 && rseg->smode == SmUpper
4202 && rseg->end+1 == aseg->start) {
4203 Addr end = *addr + *len;
4204 *addr = aseg->start;
4205 *len = end - aseg->start;
4206 *prot &= ~VKI_PROT_GROWSDOWN;
4207 } else {
4208 SET_STATUS_Failure( VKI_EINVAL );
4210 } else if (grows == VKI_PROT_GROWSUP) {
4211 rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
4212 if (rseg
4213 && rseg->kind == SkResvn
4214 && rseg->smode == SmLower
4215 && aseg->end+1 == rseg->start) {
4216 *len = aseg->end - *addr + 1;
4217 *prot &= ~VKI_PROT_GROWSUP;
4218 } else {
4219 SET_STATUS_Failure( VKI_EINVAL );
4221 } else {
4222 /* both GROWSUP and GROWSDOWN */
4223 SET_STATUS_Failure( VKI_EINVAL );
4226 #endif // defined(VKI_PROT_GROWSDOWN)
4229 POST(sys_mprotect)
4231 Addr a = ARG1;
4232 SizeT len = ARG2;
4233 Int prot = ARG3;
4235 ML_(notify_core_and_tool_of_mprotect)(a, len, prot);
4238 PRE(sys_munmap)
4240 if (0) VG_(printf)(" munmap( %#" FMT_REGWORD "x )\n", ARG1);
4241 PRINT("sys_munmap ( %#" FMT_REGWORD "x, %llu )", ARG1,(ULong)ARG2);
4242 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
4244 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
4245 SET_STATUS_Failure( VKI_EINVAL );
4248 POST(sys_munmap)
4250 Addr a = ARG1;
4251 SizeT len = ARG2;
4253 ML_(notify_core_and_tool_of_munmap)( a, len );
4256 PRE(sys_mincore)
4258 PRINT("sys_mincore ( %#" FMT_REGWORD "x, %llu, %#" FMT_REGWORD "x )",
4259 ARG1, (ULong)ARG2, ARG3);
4260 PRE_REG_READ3(long, "mincore",
4261 unsigned long, start, vki_size_t, length,
4262 unsigned char *, vec);
4263 PRE_MEM_WRITE( "mincore(vec)", ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
4265 POST(sys_mincore)
4267 POST_MEM_WRITE( ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
4270 PRE(sys_nanosleep)
4272 *flags |= SfMayBlock|SfPostOnFail;
4273 PRINT("sys_nanosleep ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4274 PRE_REG_READ2(long, "nanosleep",
4275 struct timespec *, req, struct timespec *, rem);
4276 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4277 if (ARG2 != 0)
4278 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
4281 POST(sys_nanosleep)
4283 vg_assert(SUCCESS || FAILURE);
4284 if (ARG2 != 0 && FAILURE && ERR == VKI_EINTR)
4285 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
4288 #if defined(VGO_linux) || defined(VGO_solaris)
4289 /* Handles the case where the open is of /proc/self/auxv or
4290 /proc/<pid>/auxv, and just gives out a copy of the fd for the
4291 fake file we cooked up at startup (in m_main). Also, seeks the
4292 cloned fd back to the start.
4293 Returns True if auxv open was handled (status is set). */
4294 Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename,
4295 int flags)
4297 HChar name[30]; // large enough
4299 if (!ML_(safe_to_deref)((const void *) filename, 1))
4300 return False;
4302 /* Opening /proc/<pid>/auxv or /proc/self/auxv? */
4303 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
4304 if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/auxv"))
4305 return False;
4307 /* Allow to open the file only for reading. */
4308 if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
4309 SET_STATUS_Failure(VKI_EACCES);
4310 return True;
4313 # if defined(VGO_solaris)
4314 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_auxv_fd));
4315 SysRes sres = VG_(open)(name, flags, 0);
4316 SET_STATUS_from_SysRes(sres);
4317 # else
4318 SysRes sres = VG_(dup)(VG_(cl_auxv_fd));
4319 SET_STATUS_from_SysRes(sres);
4320 if (!sr_isError(sres)) {
4321 OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
4322 if (off < 0)
4323 SET_STATUS_Failure(VKI_EMFILE);
4325 # endif
4327 return True;
4329 #endif // defined(VGO_linux) || defined(VGO_solaris)
4331 #if defined(VGO_linux)
4332 Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename,
4333 int flags)
4335 HChar name[30]; // large enough for /proc/<int>/exe
4337 if (!ML_(safe_to_deref)((const void *) filename, 1))
4338 return False;
4340 /* Opening /proc/<pid>/exe or /proc/self/exe? */
4341 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
4342 if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe"))
4343 return False;
4345 /* Allow to open the file only for reading. */
4346 if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
4347 SET_STATUS_Failure(VKI_EACCES);
4348 return True;
4351 SysRes sres = VG_(dup)(VG_(cl_exec_fd));
4352 SET_STATUS_from_SysRes(sres);
4353 if (!sr_isError(sres)) {
4354 OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
4355 if (off < 0)
4356 SET_STATUS_Failure(VKI_EMFILE);
4359 return True;
4361 #endif // defined(VGO_linux)
4363 PRE(sys_open)
4365 if (ARG2 & VKI_O_CREAT) {
4366 // 3-arg version
4367 PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld, %ld )",ARG1,
4368 (HChar*)(Addr)ARG1, SARG2, SARG3);
4369 PRE_REG_READ3(long, "open",
4370 const char *, filename, int, flags, int, mode);
4371 } else {
4372 // 2-arg version
4373 PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld )",ARG1,
4374 (HChar*)(Addr)ARG1, SARG2);
4375 PRE_REG_READ2(long, "open",
4376 const char *, filename, int, flags);
4378 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
4380 #if defined(VGO_linux)
4381 /* Handle the case where the open is of /proc/self/cmdline or
4382 /proc/<pid>/cmdline, and just give it a copy of the fd for the
4383 fake file we cooked up at startup (in m_main). Also, seek the
4384 cloned fd back to the start. */
4386 HChar name[30]; // large enough
4387 HChar* arg1s = (HChar*) (Addr)ARG1;
4388 SysRes sres;
4390 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
4391 if (ML_(safe_to_deref)( arg1s, 1 )
4392 && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/cmdline"))) {
4393 sres = VG_(dup)( VG_(cl_cmdline_fd) );
4394 SET_STATUS_from_SysRes( sres );
4395 if (!sr_isError(sres)) {
4396 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
4397 if (off < 0)
4398 SET_STATUS_Failure( VKI_EMFILE );
4400 return;
4404 /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv
4405 or /proc/self/exe or /proc/<pid>/exe. */
4406 if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2)
4407 || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2))
4408 return;
4409 #endif // defined(VGO_linux)
4411 /* Otherwise handle normally */
4412 *flags |= SfMayBlock;
4415 POST(sys_open)
4417 vg_assert(SUCCESS);
4418 if (!ML_(fd_allowed)(RES, "open", tid, True)) {
4419 VG_(close)(RES);
4420 SET_STATUS_Failure( VKI_EMFILE );
4421 } else {
4422 if (VG_(clo_track_fds))
4423 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
4427 PRE(sys_read)
4429 *flags |= SfMayBlock;
4430 PRINT("sys_read ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4431 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4432 PRE_REG_READ3(ssize_t, "read",
4433 int, fd, char *, buf, vki_size_t, count);
4435 if (!ML_(fd_allowed)(ARG1, "read", tid, False))
4436 SET_STATUS_Failure( VKI_EBADF );
4437 else
4438 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
4441 POST(sys_read)
4443 vg_assert(SUCCESS);
4444 POST_MEM_WRITE( ARG2, RES );
4447 PRE(sys_write)
4449 Bool ok;
4450 *flags |= SfMayBlock;
4451 PRINT("sys_write ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4452 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4453 PRE_REG_READ3(ssize_t, "write",
4454 unsigned int, fd, const char *, buf, vki_size_t, count);
4455 /* check to see if it is allowed. If not, try for an exemption from
4456 --sim-hints=enable-outer (used for self hosting). */
4457 ok = ML_(fd_allowed)(ARG1, "write", tid, False);
4458 if (!ok && ARG1 == 2/*stderr*/
4459 && SimHintiS(SimHint_enable_outer, VG_(clo_sim_hints)))
4460 ok = True;
4461 #if defined(VGO_solaris)
4462 if (!ok && VG_(vfork_fildes_addr) != NULL
4463 && *VG_(vfork_fildes_addr) >= 0 && *VG_(vfork_fildes_addr) == ARG1)
4464 ok = True;
4465 #endif
4466 if (!ok)
4467 SET_STATUS_Failure( VKI_EBADF );
4468 else
4469 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
4472 PRE(sys_creat)
4474 *flags |= SfMayBlock;
4475 PRINT("sys_creat ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
4476 (HChar*)(Addr)ARG1, SARG2);
4477 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
4478 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
4481 POST(sys_creat)
4483 vg_assert(SUCCESS);
4484 if (!ML_(fd_allowed)(RES, "creat", tid, True)) {
4485 VG_(close)(RES);
4486 SET_STATUS_Failure( VKI_EMFILE );
4487 } else {
4488 if (VG_(clo_track_fds))
4489 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
4493 PRE(sys_poll)
4495 /* struct pollfd {
4496 int fd; -- file descriptor
4497 short events; -- requested events
4498 short revents; -- returned events
4500 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
4502 UInt i;
4503 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
4504 *flags |= SfMayBlock;
4505 PRINT("sys_poll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )\n",
4506 ARG1, ARG2, SARG3);
4507 PRE_REG_READ3(long, "poll",
4508 struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout);
4510 for (i = 0; i < ARG2; i++) {
4511 PRE_MEM_READ( "poll(ufds.fd)",
4512 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
4513 if (ML_(safe_to_deref)(&ufds[i].fd, sizeof(ufds[i].fd)) && ufds[i].fd >= 0) {
4514 PRE_MEM_READ( "poll(ufds.events)",
4515 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
4517 PRE_MEM_WRITE( "poll(ufds.revents)",
4518 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
4522 POST(sys_poll)
4524 if (SUCCESS) {
4525 UInt i;
4526 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
4527 for (i = 0; i < ARG2; i++)
4528 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
4532 PRE(sys_readlink)
4534 FUSE_COMPATIBLE_MAY_BLOCK();
4535 Word saved = SYSNO;
4537 PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )",
4538 ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3);
4539 PRE_REG_READ3(long, "readlink",
4540 const char *, path, char *, buf, int, bufsiz);
4541 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4542 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
4546 #if defined(VGO_linux) || defined(VGO_solaris)
4547 #if defined(VGO_linux)
4548 #define PID_EXEPATH "/proc/%d/exe"
4549 #define SELF_EXEPATH "/proc/self/exe"
4550 #define SELF_EXEFD "/proc/self/fd/%d"
4551 #elif defined(VGO_solaris)
4552 #define PID_EXEPATH "/proc/%d/path/a.out"
4553 #define SELF_EXEPATH "/proc/self/path/a.out"
4554 #define SELF_EXEFD "/proc/self/path/%d"
4555 #endif
4557 * Handle the case where readlink is looking at /proc/self/exe or
4558 * /proc/<pid>/exe, or equivalent on Solaris.
4560 HChar name[30]; // large enough
4561 HChar* arg1s = (HChar*) (Addr)ARG1;
4562 VG_(sprintf)(name, PID_EXEPATH, VG_(getpid)());
4563 if (ML_(safe_to_deref)(arg1s, 1)
4564 && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, SELF_EXEPATH))) {
4565 VG_(sprintf)(name, SELF_EXEFD, VG_(cl_exec_fd));
4566 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name,
4567 ARG2, ARG3));
4568 } else
4569 #endif
4571 /* Normal case */
4572 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
4576 if (SUCCESS && RES > 0)
4577 POST_MEM_WRITE( ARG2, RES );
4580 PRE(sys_readv)
4582 Int i;
4583 struct vki_iovec * vec;
4584 char buf[sizeof("readv(vector[])") + 11];
4585 *flags |= SfMayBlock;
4586 PRINT("sys_readv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4587 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4588 PRE_REG_READ3(ssize_t, "readv",
4589 unsigned long, fd, const struct iovec *, vector,
4590 unsigned long, count);
4591 if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
4592 SET_STATUS_Failure( VKI_EBADF );
4593 } else {
4594 if ((Int)ARG3 >= 0)
4595 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
4597 if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) {
4598 vec = (struct vki_iovec *)(Addr)ARG2;
4599 for (i = 0; i < (Int)ARG3; i++) {
4600 VG_(sprintf)(buf, "readv(vector[%d])", i);
4601 PRE_MEM_WRITE(buf, (Addr)vec[i].iov_base, vec[i].iov_len );
4607 POST(sys_readv)
4609 vg_assert(SUCCESS);
4610 if (RES > 0) {
4611 Int i;
4612 struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
4613 Int remains = RES;
4615 /* RES holds the number of bytes read. */
4616 for (i = 0; i < (Int)ARG3; i++) {
4617 Int nReadThisBuf = vec[i].iov_len;
4618 if (nReadThisBuf > remains) nReadThisBuf = remains;
4619 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4620 remains -= nReadThisBuf;
4621 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4626 PRE(sys_rename)
4628 FUSE_COMPATIBLE_MAY_BLOCK();
4629 PRINT("sys_rename ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )", ARG1,
4630 (char*)(Addr)ARG1,ARG2,(char*)(Addr)ARG2);
4631 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
4632 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4633 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
4636 PRE(sys_rmdir)
4638 *flags |= SfMayBlock;
4639 PRINT("sys_rmdir ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
4640 PRE_REG_READ1(long, "rmdir", const char *, pathname);
4641 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
4644 PRE(sys_select)
4646 *flags |= SfMayBlock;
4647 PRINT("sys_select ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4648 FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4, ARG5);
4649 PRE_REG_READ5(long, "select",
4650 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4651 vki_fd_set *, exceptfds, struct vki_timeval *, timeout);
4652 // XXX: this possibly understates how much memory is read.
4653 if (ARG2 != 0)
4654 PRE_MEM_READ( "select(readfds)",
4655 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4656 if (ARG3 != 0)
4657 PRE_MEM_READ( "select(writefds)",
4658 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4659 if (ARG4 != 0)
4660 PRE_MEM_READ( "select(exceptfds)",
4661 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4662 if (ARG5 != 0)
4663 PRE_timeval_READ( "select(timeout)", (Addr)ARG5 );
4666 PRE(sys_setgid)
4668 PRINT("sys_setgid ( %" FMT_REGWORD "u )", ARG1);
4669 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
4672 PRE(sys_setsid)
4674 PRINT("sys_setsid ( )");
4675 PRE_REG_READ0(long, "setsid");
4678 PRE(sys_setgroups)
4680 PRINT("setgroups ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
4681 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
4682 if (ARG1 > 0)
4683 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
4686 PRE(sys_setpgid)
4688 PRINT("setpgid ( %ld, %ld )", SARG1, SARG2);
4689 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
4692 PRE(sys_setregid)
4694 PRINT("sys_setregid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
4695 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
4698 PRE(sys_setreuid)
4700 PRINT("sys_setreuid ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
4701 ARG1, ARG2);
4702 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
4705 PRE(sys_setrlimit)
4707 UWord arg1 = ARG1;
4708 PRINT("sys_setrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
4709 PRE_REG_READ2(long, "setrlimit",
4710 unsigned int, resource, struct rlimit *, rlim);
4711 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
4713 #ifdef _RLIMIT_POSIX_FLAG
4714 // Darwin will sometimes set _RLIMIT_POSIX_FLAG on setrlimit calls.
4715 // Unset it here to make the if statements below work correctly.
4716 arg1 &= ~_RLIMIT_POSIX_FLAG;
4717 #endif
4719 if (!VG_(am_is_valid_for_client)(ARG2, sizeof(struct vki_rlimit),
4720 VKI_PROT_READ)) {
4721 SET_STATUS_Failure( VKI_EFAULT );
4723 else if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4724 > ((struct vki_rlimit *)(Addr)ARG2)->rlim_max) {
4725 #if defined(VGO_freebsd)
4726 SET_STATUS_Failure( VKI_EPERM );
4727 #else
4728 SET_STATUS_Failure( VKI_EINVAL );
4729 #endif
4731 else if (arg1 == VKI_RLIMIT_NOFILE) {
4732 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4733 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max != VG_(fd_hard_limit)) {
4734 SET_STATUS_Failure( VKI_EPERM );
4736 else {
4737 VG_(fd_soft_limit) = ((struct vki_rlimit *)(Addr)ARG2)->rlim_cur;
4738 SET_STATUS_Success( 0 );
4741 else if (arg1 == VKI_RLIMIT_DATA) {
4742 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4743 > VG_(client_rlimit_data).rlim_max ||
4744 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max
4745 > VG_(client_rlimit_data).rlim_max) {
4746 SET_STATUS_Failure( VKI_EPERM );
4748 else {
4749 VG_(client_rlimit_data) = *(struct vki_rlimit *)(Addr)ARG2;
4750 SET_STATUS_Success( 0 );
4753 else if (arg1 == VKI_RLIMIT_STACK && tid == 1) {
4754 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4755 > VG_(client_rlimit_stack).rlim_max ||
4756 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max
4757 > VG_(client_rlimit_stack).rlim_max) {
4758 SET_STATUS_Failure( VKI_EPERM );
4760 else {
4761 /* Change the value of client_stack_szB to the rlim_cur value but
4762 only if it is smaller than the size of the allocated stack for the
4763 client.
4764 TODO: All platforms should set VG_(clstk_max_size) as part of their
4765 setup_client_stack(). */
4766 if ((VG_(clstk_max_size) == 0)
4767 || (((struct vki_rlimit *) (Addr)ARG2)->rlim_cur <= VG_(clstk_max_size)))
4768 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)(Addr)ARG2)->rlim_cur;
4770 VG_(client_rlimit_stack) = *(struct vki_rlimit *)(Addr)ARG2;
4771 SET_STATUS_Success( 0 );
4776 PRE(sys_setuid)
4778 PRINT("sys_setuid ( %" FMT_REGWORD "u )", ARG1);
4779 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4782 #if !defined(VGP_nanomips_linux) && !defined(VGO_freebsd)
4783 PRE(sys_newstat)
4785 FUSE_COMPATIBLE_MAY_BLOCK();
4786 PRINT("sys_newstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4787 ARG1,(char*)(Addr)ARG1,ARG2);
4788 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
4789 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
4790 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
4793 POST(sys_newstat)
4795 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4797 #endif
4799 #if !defined(VGP_nanomips_linux)
4800 PRE(sys_statfs)
4802 FUSE_COMPATIBLE_MAY_BLOCK();
4803 PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4804 ARG1, (char*)(Addr)ARG1, ARG2);
4805 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
4806 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
4807 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
4809 POST(sys_statfs)
4811 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
4814 PRE(sys_statfs64)
4816 PRINT("sys_statfs64 ( %#" FMT_REGWORD "x(%s), %llu, %#" FMT_REGWORD "x )",
4817 ARG1, (char*)(Addr)ARG1, (ULong)ARG2, ARG3);
4818 PRE_REG_READ3(long, "statfs64",
4819 const char *, path, vki_size_t, size, struct statfs64 *, buf);
4820 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
4821 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
4823 POST(sys_statfs64)
4825 POST_MEM_WRITE( ARG3, ARG2 );
4827 #endif
4829 PRE(sys_symlink)
4831 *flags |= SfMayBlock;
4832 PRINT("sys_symlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )",
4833 ARG1, (char*)(Addr)ARG1, ARG2, (char*)(Addr)ARG2);
4834 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
4835 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
4836 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
4839 PRE(sys_time)
4841 /* time_t time(time_t *t); */
4842 PRINT("sys_time ( %#" FMT_REGWORD "x )",ARG1);
4843 PRE_REG_READ1(long, "time", int *, t);
4844 if (ARG1 != 0) {
4845 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
4849 POST(sys_time)
4851 if (ARG1 != 0) {
4852 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
4856 PRE(sys_times)
4858 PRINT("sys_times ( %#" FMT_REGWORD "x )", ARG1);
4859 PRE_REG_READ1(long, "times", struct tms *, buf);
4860 if (ARG1 != 0) {
4861 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
4865 POST(sys_times)
4867 if (ARG1 != 0) {
4868 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
4872 PRE(sys_umask)
4874 PRINT("sys_umask ( %ld )", SARG1);
4875 PRE_REG_READ1(long, "umask", int, mask);
4878 PRE(sys_unlink)
4880 *flags |= SfMayBlock;
4881 PRINT("sys_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
4882 PRE_REG_READ1(long, "unlink", const char *, pathname);
4883 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
4886 #if !defined(VGO_freebsd)
4887 PRE(sys_newuname)
4889 PRINT("sys_newuname ( %#" FMT_REGWORD "x )", ARG1);
4890 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
4891 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
4894 POST(sys_newuname)
4896 if (ARG1 != 0) {
4897 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
4900 #endif
4902 PRE(sys_waitpid)
4904 *flags |= SfMayBlock;
4905 PRINT("sys_waitpid ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4906 PRE_REG_READ3(long, "waitpid",
4907 vki_pid_t, pid, unsigned int *, status, int, options);
4909 if (ARG2 != (Addr)NULL)
4910 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
4913 POST(sys_waitpid)
4915 if (ARG2 != (Addr)NULL)
4916 POST_MEM_WRITE( ARG2, sizeof(int) );
4919 PRE(sys_wait4)
4921 *flags |= SfMayBlock;
4922 PRINT("sys_wait4 ( %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
4923 SARG1, ARG2, SARG3, ARG4);
4925 PRE_REG_READ4(long, "wait4",
4926 vki_pid_t, pid, unsigned int *, status, int, options,
4927 struct rusage *, rusage);
4928 if (ARG2 != (Addr)NULL)
4929 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
4930 if (ARG4 != (Addr)NULL)
4931 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
4934 POST(sys_wait4)
4936 if (ARG2 != (Addr)NULL)
4937 POST_MEM_WRITE( ARG2, sizeof(int) );
4938 if (ARG4 != (Addr)NULL)
4939 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
4942 PRE(sys_writev)
4944 Int i;
4945 struct vki_iovec * vec;
4946 char buf[sizeof("writev(vector[])") + 11];
4947 *flags |= SfMayBlock;
4948 PRINT("sys_writev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4949 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4950 PRE_REG_READ3(ssize_t, "writev",
4951 unsigned long, fd, const struct iovec *, vector,
4952 unsigned long, count);
4953 if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) {
4954 SET_STATUS_Failure( VKI_EBADF );
4955 } else {
4956 if ((Int)ARG3 >= 0)
4957 PRE_MEM_READ( "writev(vector)",
4958 ARG2, ARG3 * sizeof(struct vki_iovec) );
4960 if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) {
4961 vec = (struct vki_iovec *)(Addr)ARG2;
4962 for (i = 0; i < (Int)ARG3; i++) {
4963 VG_(sprintf)(buf, "writev(vector[%d])", i);
4964 PRE_MEM_READ( buf, (Addr)vec[i].iov_base, vec[i].iov_len );
4970 PRE(sys_utimes)
4972 FUSE_COMPATIBLE_MAY_BLOCK();
4973 PRINT("sys_utimes ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4974 ARG1, (char*)(Addr)ARG1, ARG2);
4975 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
4976 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
4977 if (ARG2 != 0) {
4978 PRE_timeval_READ( "utimes(tvp[0])", (Addr)ARG2 );
4979 PRE_timeval_READ( "utimes(tvp[1])",
4980 (Addr)ARG2+sizeof(struct vki_timeval) );
4984 PRE(sys_acct)
4986 PRINT("sys_acct ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
4987 PRE_REG_READ1(long, "acct", const char *, filename);
4988 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
4991 PRE(sys_pause)
4993 *flags |= SfMayBlock;
4994 PRINT("sys_pause ( )");
4995 PRE_REG_READ0(long, "pause");
4998 PRE(sys_sigaltstack)
5000 PRINT("sigaltstack ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
5001 PRE_REG_READ2(int, "sigaltstack",
5002 const vki_stack_t *, ss, vki_stack_t *, oss);
5003 if (ARG1 != 0) {
5004 const vki_stack_t *ss = (vki_stack_t *)(Addr)ARG1;
5005 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_sp, sizeof(ss->ss_sp) );
5006 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_flags, sizeof(ss->ss_flags) );
5007 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_size, sizeof(ss->ss_size) );
5009 if (ARG2 != 0) {
5010 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
5013 /* Be safe. */
5014 if (ARG1 && !ML_(safe_to_deref((void*)(Addr)ARG1, sizeof(vki_stack_t)))) {
5015 SET_STATUS_Failure(VKI_EFAULT);
5016 return;
5018 if (ARG2 && !ML_(safe_to_deref((void*)(Addr)ARG2, sizeof(vki_stack_t)))) {
5019 SET_STATUS_Failure(VKI_EFAULT);
5020 return;
5023 SET_STATUS_from_SysRes(
5024 VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)(Addr)ARG1,
5025 (vki_stack_t*)(Addr)ARG2)
5028 POST(sys_sigaltstack)
5030 vg_assert(SUCCESS);
5031 if (RES == 0 && ARG2 != 0)
5032 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
5035 PRE(sys_sethostname)
5037 PRINT("sys_sethostname ( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
5038 PRE_REG_READ2(long, "sethostname", char *, name, int, len);
5039 PRE_MEM_READ( "sethostname(name)", ARG1, ARG2 );
5042 #undef PRE
5043 #undef POST
5045 #endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
5047 /*--------------------------------------------------------------------*/
5048 /*--- end ---*/
5049 /*--------------------------------------------------------------------*/