FreeBSD sanity check: enable dev/ino and offset checking.
[valgrind.git] / coregrind / m_syswrap / syswrap-generic.c
blob48be8e8bf075db7947a69eb8f27e2744b4712bc2
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 HChar *description; /* Description saved before close */
544 ExeContext *where; /* NULL if inherited from parent */
545 ExeContext *where_closed; /* record the last close of fd */
546 Bool fd_closed;
547 struct OpenFd *next, *prev;
548 } OpenFd;
550 /* List of allocated file descriptors. */
551 static OpenFd *allocated_fds = NULL;
553 /* Count of open file descriptors. */
554 static Int fd_count = 0;
556 /* Close_range caller might want to close very wide range of file descriptors,
557 up to 0U. We want to avoid iterating through such a range in a normall
558 close_range, just up to any open file descriptor. Also, unlike
559 record_fd_close_range, we assume the user might deliberately double closes
560 any file descriptors in the range, so don't warn about double close here. */
561 void ML_(record_fd_close_range)(ThreadId tid, Int from_fd)
563 OpenFd *i = allocated_fds;
565 if (from_fd >= VG_(fd_hard_limit))
566 return; /* Valgrind internal */
568 while(i) {
569 // Assume the user doesn't want a warning if this came from
570 // close_range. Just record the file descriptors not yet closed here.
571 if (i->fd >= from_fd && !i->fd_closed
572 && i->fd != VG_(log_output_sink).fd
573 && i->fd != VG_(xml_output_sink).fd) {
574 i->fd_closed = True;
575 i->where_closed = ((tid == -1)
576 ? NULL
577 : VG_(record_ExeContext)(tid,
578 0/*first_ip_delta*/));
579 fd_count--;
581 i = i->next;
585 struct BadCloseExtra {
586 Int fd; /* The file descriptor */
587 HChar *pathname; /* NULL if not a regular file or unknown */
588 HChar *description; /* Description of the file descriptor
589 might include the pathname */
590 ExeContext *where_closed; /* record the last close of fd */
591 ExeContext *where_opened; /* recordwhere the fd was opened */
594 struct NotClosedExtra {
595 Int fd;
596 HChar *pathname;
597 HChar *description;
600 /* Note the fact that a file descriptor was just closed. */
601 void ML_(record_fd_close)(ThreadId tid, Int fd)
603 OpenFd *i = allocated_fds;
605 if (fd >= VG_(fd_hard_limit))
606 return; /* Valgrind internal */
608 while(i) {
609 if (i->fd == fd) {
610 if (i->fd_closed) {
611 struct BadCloseExtra bce;
612 bce.fd = i->fd;
613 bce.pathname = i->pathname;
614 bce.description = i->description;
615 bce.where_opened = i->where;
616 bce.where_closed = i->where_closed;
617 VG_(maybe_record_error)(tid, FdBadClose, 0,
618 "file descriptor already closed", &bce);
619 } else {
620 i->fd_closed = True;
621 i->where_closed = ((tid == -1)
622 ? NULL
623 : VG_(record_ExeContext)(tid,
624 0/*first_ip_delta*/));
625 /* Record path/socket name, etc. In case we want to print it later,
626 for example for double close. Note that record_fd_close is
627 actually called from the PRE syscall handler, so the file
628 description is about to be closed, but hasn't yet at this
629 point. */
630 if (!i->pathname) {
631 Int val;
632 Int len = sizeof(val);
633 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE,
634 &val, &len) == -1) {
635 HChar *pathname = VG_(malloc)("vg.record_fd_close.fd", 30);
636 VG_(snprintf)(pathname, 30, "file descriptor %d", i->fd);
637 i->description = pathname;
638 } else {
639 HChar *name = VG_(malloc)("vg.record_fd_close.sock", 256);
640 i->description = getsockdetails(i->fd, 256, name);
642 } else {
643 i->description = VG_(strdup)("vg.record_fd_close.path",
644 i->pathname);
646 fd_count--;
648 break;
650 i = i->next;
654 /* Note the fact that a file descriptor was just opened. If the
655 tid is -1, this indicates an inherited fd. If the pathname is NULL,
656 this either indicates a non-standard file (i.e. a pipe or socket or
657 some such thing) or that we don't know the filename. If the fd is
658 already open, then we're probably doing a dup2() to an existing fd,
659 so just overwrite the existing one. */
660 void ML_(record_fd_open_with_given_name)(ThreadId tid, Int fd,
661 const HChar *pathname)
663 OpenFd *i;
665 if (fd >= VG_(fd_hard_limit))
666 return; /* Valgrind internal */
668 /* Check to see if this fd is already open (or closed, we will just
669 override it. */
670 i = allocated_fds;
671 while (i) {
672 if (i->fd == fd) {
673 if (i->pathname) {
674 VG_(free)(i->pathname);
675 i->pathname = NULL;
677 if (i->description) {
678 VG_(free)(i->description);
679 i->description = NULL;
681 if (i->fd_closed) /* now we will open it. */
682 fd_count++;
683 break;
685 i = i->next;
688 /* Not already one: allocate an OpenFd */
689 if (i == NULL) {
690 i = VG_(malloc)("syswrap.rfdowgn.1", sizeof(OpenFd));
692 i->prev = NULL;
693 i->next = allocated_fds;
694 if(allocated_fds) allocated_fds->prev = i;
695 allocated_fds = i;
696 fd_count++;
699 i->fd = fd;
700 i->pathname = VG_(strdup)("syswrap.rfdowgn.2", pathname);
701 i->description = NULL; /* Only set on close. */
702 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
703 i->fd_closed = False;
704 i->where_closed = NULL;
707 // Record opening of an fd, and find its name.
708 void ML_(record_fd_open_named)(ThreadId tid, Int fd)
710 const HChar* buf;
711 const HChar* name;
712 if (VG_(resolve_filename)(fd, &buf))
713 name = buf;
714 else
715 name = NULL;
717 ML_(record_fd_open_with_given_name)(tid, fd, name);
720 // Record opening of a nameless fd.
721 void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
723 ML_(record_fd_open_with_given_name)(tid, fd, NULL);
726 // Return if a given file descriptor is already recorded.
727 Bool ML_(fd_recorded)(Int fd)
729 OpenFd *i = allocated_fds;
730 while (i) {
731 if (i->fd == fd) {
732 if (i->fd_closed)
733 return False;
734 else
735 return True;
737 i = i->next;
739 return False;
742 /* Returned string must not be modified nor free'd. */
743 const HChar *ML_(find_fd_recorded_by_fd)(Int fd)
745 OpenFd *i = allocated_fds;
747 while (i) {
748 if (i->fd == fd) {
749 if (i->fd_closed)
750 return NULL;
751 else
752 return i->pathname;
754 i = i->next;
757 return NULL;
760 static
761 HChar *unix_to_name(struct vki_sockaddr_un *sa, UInt len, HChar *name)
763 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
764 VG_(sprintf)(name, "<unknown>");
765 } else {
766 VG_(sprintf)(name, "%s", sa->sun_path);
769 return name;
772 static
773 HChar *inet_to_name(struct vki_sockaddr_in *sa, UInt len, HChar *name)
775 if (sa == NULL || len == 0) {
776 VG_(sprintf)(name, "<unknown>");
777 } else if (sa->sin_port == 0) {
778 VG_(sprintf)(name, "<unbound>");
779 } else {
780 UInt addr = VG_(ntohl)(sa->sin_addr.s_addr);
781 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
782 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
783 (addr>>8) & 0xFF, addr & 0xFF,
784 VG_(ntohs)(sa->sin_port));
787 return name;
790 static
791 void inet6_format(HChar *s, const UChar ip[16])
793 static const unsigned char V4mappedprefix[12] = {0,0,0,0,0,0,0,0,0,0,0xff,0xff};
795 if (!VG_(memcmp)(ip, V4mappedprefix, 12)) {
796 const struct vki_in_addr *sin_addr =
797 (const struct vki_in_addr *)(ip + 12);
798 UInt addr = VG_(ntohl)(sin_addr->s_addr);
800 VG_(sprintf)(s, "::ffff:%u.%u.%u.%u",
801 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
802 (addr>>8) & 0xFF, addr & 0xFF);
803 } else {
804 Bool compressing = False;
805 Bool compressed = False;
806 Int len = 0;
807 Int i;
809 for (i = 0; i < 16; i += 2) {
810 UInt word = ((UInt)ip[i] << 8) | (UInt)ip[i+1];
811 if (word == 0 && !compressed) {
812 compressing = True;
813 } else {
814 if (compressing) {
815 compressing = False;
816 compressed = True;
817 s[len++] = ':';
819 if (i > 0) {
820 s[len++] = ':';
822 len += VG_(sprintf)(s + len, "%x", word);
826 if (compressing) {
827 s[len++] = ':';
828 s[len++] = ':';
831 s[len++] = 0;
834 return;
837 static
838 HChar *inet6_to_name(struct vki_sockaddr_in6 *sa, UInt len, HChar *name)
840 if (sa == NULL || len == 0) {
841 VG_(sprintf)(name, "<unknown>");
842 } else if (sa->sin6_port == 0) {
843 VG_(sprintf)(name, "<unbound>");
844 } else {
845 HChar addr[100]; // large enough
846 inet6_format(addr, (void *)&(sa->sin6_addr));
847 VG_(sprintf)(name, "[%s]:%u", addr, VG_(ntohs)(sa->sin6_port));
850 return name;
854 * Try get some details about a socket.
855 * Returns the given BUF with max length LEN.
857 static
858 HChar *getsockdetails(Int fd, UInt len, HChar *buf)
860 union u {
861 struct vki_sockaddr a;
862 struct vki_sockaddr_in in;
863 struct vki_sockaddr_in6 in6;
864 struct vki_sockaddr_un un;
865 } laddr;
866 Int llen;
868 llen = sizeof(laddr);
869 VG_(memset)(&laddr, 0, llen);
871 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
872 switch(laddr.a.sa_family) {
873 case VKI_AF_INET: {
874 HChar lname[32]; // large enough
875 HChar pname[32]; // large enough
876 struct vki_sockaddr_in paddr;
877 Int plen = sizeof(struct vki_sockaddr_in);
879 if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
880 VG_(snprintf)(buf, len, "AF_INET socket %d: %s <-> %s", fd,
881 inet_to_name(&(laddr.in), llen, lname),
882 inet_to_name(&paddr, plen, pname));
883 return buf;
884 } else {
885 VG_(snprintf)(buf, len, "AF_INET socket %d: %s <-> <unbound>",
886 fd, inet_to_name(&(laddr.in), llen, lname));
887 return buf;
890 case VKI_AF_INET6: {
891 HChar lname[128]; // large enough
892 HChar pname[128]; // large enough
893 struct vki_sockaddr_in6 paddr;
894 Int plen = sizeof(struct vki_sockaddr_in6);
896 if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
897 VG_(snprintf)(buf, len, "AF_INET6 socket %d: %s <-> %s", fd,
898 inet6_to_name(&(laddr.in6), llen, lname),
899 inet6_to_name(&paddr, plen, pname));
900 return buf;
901 } else {
902 VG_(snprintf)(buf, len, "AF_INET6 socket %d: %s <-> <unbound>",
903 fd, inet6_to_name(&(laddr.in6), llen, lname));
904 return buf;
907 case VKI_AF_UNIX: {
908 static char lname[256];
909 VG_(snprintf)(buf, len, "AF_UNIX socket %d: %s", fd,
910 unix_to_name(&(laddr.un), llen, lname));
911 return buf;
913 default:
914 VG_(snprintf)(buf, len, "pf-%d socket %d",
915 laddr.a.sa_family, fd);
916 return buf;
920 VG_(snprintf)(buf, len, "socket %d", fd);
921 return buf;
925 /* Dump out a summary, and a more detailed list, of open file descriptors. */
926 void VG_(show_open_fds) (const HChar* when)
928 OpenFd *i;
929 int non_std = 0;
931 for (i = allocated_fds; i; i = i->next) {
932 if (i->fd > 2 && i->fd_closed != True)
933 non_std++;
936 /* If we are running quiet and there are either no open file descriptors
937 or not tracking all fds, then don't report anything. */
938 if ((fd_count == 0
939 || ((non_std == 0) && (VG_(clo_track_fds) < 2)))
940 && (VG_(clo_verbosity) == 0))
941 return;
943 if (!VG_(clo_xml)) {
944 VG_(umsg)("FILE DESCRIPTORS: %d open (%d std) %s.\n",
945 fd_count, fd_count - non_std, when);
948 for (i = allocated_fds; i; i = i->next) {
949 if (i->fd_closed)
950 continue;
952 if (i->fd <= 2 && VG_(clo_track_fds) < 2)
953 continue;
955 struct NotClosedExtra nce;
956 /* The file descriptor was not yet closed, so the description field was
957 also not yet set. Set it now as if the file descriptor was closed at
958 this point. */
959 i->description = VG_(malloc)("vg.notclosedextra.descriptor", 256);
960 if (i->pathname) {
961 VG_(snprintf) (i->description, 256, "file descriptor %d: %s",
962 i->fd, i->pathname);
963 } else {
964 Int val;
965 Int len = sizeof(val);
967 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len)
968 == -1) {
969 /* Don't want the : at the end in xml */
970 const HChar *colon = VG_(clo_xml) ? "" : ":";
971 VG_(sprintf)(i->description, "file descriptor %d%s", i->fd, colon);
972 } else {
973 getsockdetails(i->fd, 256, i->description);
977 nce.fd = i->fd;
978 nce.pathname = i->pathname;
979 nce.description = i->description;
980 VG_(unique_error) (1 /* Fake ThreadId */,
981 FdNotClosed,
982 0, /* Addr */
983 "Still Open file descriptor",
984 &nce, /* extra */
985 i->where,
986 True, /* print_error */
987 False, /* allow_GDB_attach */
988 True /* count_error */);
992 if (!VG_(clo_xml))
993 VG_(message)(Vg_UserMsg, "\n");
996 /* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't
997 have /proc support compiled in, or a non-Linux kernel), then we need to
998 find out what file descriptors we inherited from our parent process the
999 hard way - by checking each fd in turn. */
1000 static
1001 void init_preopened_fds_without_proc_self_fd(void)
1003 struct vki_rlimit lim;
1004 UInt count;
1005 Int i;
1007 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
1008 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
1009 an arbitrarily high number. 1024 happens to be the limit in
1010 the 2.4 Linux kernels. */
1011 count = 1024;
1012 } else {
1013 count = lim.rlim_cur;
1016 for (i = 0; i < count; i++)
1017 if (VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
1018 ML_(record_fd_open_named)(-1, i);
1021 /* Initialize the list of open file descriptors with the file descriptors
1022 we inherited from out parent process. */
1024 void VG_(init_preopened_fds)(void)
1026 // DDD: should probably use HAVE_PROC here or similar, instead.
1027 #if defined(VGO_linux)
1028 Int ret;
1029 struct vki_dirent64 d;
1030 SysRes f;
1032 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
1033 if (sr_isError(f)) {
1034 init_preopened_fds_without_proc_self_fd();
1035 return;
1038 while ((ret = VG_(getdents64)(sr_Res(f), &d, sizeof(d))) != 0) {
1039 if (ret == -1)
1040 goto out;
1042 if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
1043 HChar* s;
1044 Int fno = VG_(strtoll10)(d.d_name, &s);
1045 if (*s == '\0') {
1046 if (fno != sr_Res(f))
1047 if (VG_(clo_track_fds))
1048 ML_(record_fd_open_named)(-1, fno);
1049 } else {
1050 VG_(message)(Vg_DebugMsg,
1051 "Warning: invalid file name in /proc/self/fd: %s\n",
1052 d.d_name);
1056 VG_(lseek)(sr_Res(f), d.d_off, VKI_SEEK_SET);
1059 out:
1060 VG_(close)(sr_Res(f));
1062 #elif defined(VGO_darwin) || defined(VGO_freebsd)
1063 init_preopened_fds_without_proc_self_fd();
1065 #elif defined(VGO_solaris)
1066 Int ret;
1067 Char buf[VKI_MAXGETDENTS_SIZE];
1068 SysRes f;
1070 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
1071 if (sr_isError(f)) {
1072 init_preopened_fds_without_proc_self_fd();
1073 return;
1076 while ((ret = VG_(getdents64)(sr_Res(f), (struct vki_dirent64 *) buf,
1077 sizeof(buf))) > 0) {
1078 Int i = 0;
1079 while (i < ret) {
1080 /* Proceed one entry. */
1081 struct vki_dirent64 *d = (struct vki_dirent64 *) (buf + i);
1082 if (VG_(strcmp)(d->d_name, ".") && VG_(strcmp)(d->d_name, "..")) {
1083 HChar *s;
1084 Int fno = VG_(strtoll10)(d->d_name, &s);
1085 if (*s == '\0') {
1086 if (fno != sr_Res(f))
1087 if (VG_(clo_track_fds))
1088 ML_(record_fd_open_named)(-1, fno);
1089 } else {
1090 VG_(message)(Vg_DebugMsg,
1091 "Warning: invalid file name in /proc/self/fd: %s\n",
1092 d->d_name);
1096 /* Move on the next entry. */
1097 i += d->d_reclen;
1101 VG_(close)(sr_Res(f));
1103 #else
1104 # error Unknown OS
1105 #endif
1108 Bool fd_eq_Error (VgRes res, const Error *e1, const Error *e2)
1110 // XXX should we compare the fds?
1111 return False;
1114 void fd_before_pp_Error (const Error *err)
1116 // Nothing to do here
1119 void fd_pp_Error (const Error *err)
1121 const Bool xml = VG_(clo_xml);
1122 const HChar* whatpre = VG_(clo_xml) ? " <what>" : "";
1123 const HChar* whatpost = VG_(clo_xml) ? "</what>" : "";
1124 const HChar* auxpre = VG_(clo_xml) ? " <auxwhat>" : " ";
1125 const HChar* auxpost = VG_(clo_xml) ? "</auxwhat>" : "";
1126 ExeContext *where = VG_(get_error_where)(err);
1127 if (VG_(get_error_kind)(err) == FdBadClose) {
1128 if (xml) VG_(emit)(" <kind>FdBadClose</kind>\n");
1129 struct BadCloseExtra *bce = (struct BadCloseExtra *)
1130 VG_(get_error_extra)(err);
1131 vg_assert(bce);
1132 if (xml) {
1133 VG_(emit)(" <fd>%d</fd>\n", bce->fd);
1134 if (bce->pathname)
1135 VG_(emit)(" <path>%s</path>\n", bce->pathname);
1137 VG_(emit)("%sFile descriptor %d: %s is already closed%s\n",
1138 whatpre, bce->fd, bce->description, whatpost);
1139 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
1140 VG_(emit)("%sPreviously closed%s\n", auxpre, auxpost);
1141 VG_(pp_ExeContext)(bce->where_closed);
1142 VG_(emit)("%sOriginally opened%s\n", auxpre, auxpost);
1143 VG_(pp_ExeContext)(bce->where_opened);
1144 } else if (VG_(get_error_kind)(err) == FdNotClosed) {
1145 if (xml) VG_(emit)(" <kind>FdNotClosed</kind>\n");
1146 struct NotClosedExtra *nce = (struct NotClosedExtra *)
1147 VG_(get_error_extra)(err);
1148 if (xml) {
1149 VG_(emit)(" <fd>%d</fd>\n", nce->fd);
1150 if (nce->pathname)
1151 VG_(emit)(" <path>%s</path>\n", nce->pathname);
1153 VG_(emit)("%sOpen %s%s\n", whatpre, nce->description, whatpost);
1154 if (where != NULL) {
1155 VG_(pp_ExeContext)(where);
1156 if (!xml) VG_(message)(Vg_UserMsg, "\n");
1157 } else if (!xml) {
1158 VG_(message)(Vg_UserMsg, " <inherited from parent>\n");
1159 VG_(message)(Vg_UserMsg, "\n");
1161 } else {
1162 vg_assert2 (False, "Unknown error kind: %d",
1163 VG_(get_error_kind)(err));
1167 /* Called to see if there is any extra state to be saved with this
1168 error. Must return the size of the extra struct. */
1169 UInt fd_update_extra (const Error *err)
1171 if (VG_(get_error_kind)(err) == FdBadClose)
1172 return sizeof (struct BadCloseExtra);
1173 else if (VG_(get_error_kind)(err) == FdNotClosed)
1174 return sizeof (struct NotClosedExtra);
1175 else {
1176 vg_assert2 (False, "Unknown error kind: %d",
1177 VG_(get_error_kind)(err));
1181 static
1182 void pre_mem_read_sendmsg ( ThreadId tid, Bool read,
1183 const HChar *msg, Addr base, SizeT size )
1185 HChar outmsg[VG_(strlen)(msg) + 10]; // large enough
1186 VG_(sprintf)(outmsg, "sendmsg%s", msg);
1187 PRE_MEM_READ( outmsg, base, size );
1190 static
1191 void pre_mem_write_recvmsg ( ThreadId tid, Bool read,
1192 const HChar *msg, Addr base, SizeT size )
1194 HChar outmsg[VG_(strlen)(msg) + 10]; // large enough
1195 VG_(sprintf)(outmsg, "recvmsg%s", msg);
1196 if ( read )
1197 PRE_MEM_READ( outmsg, base, size );
1198 else
1199 PRE_MEM_WRITE( outmsg, base, size );
1202 static
1203 void post_mem_write_recvmsg ( ThreadId tid, Bool read,
1204 const HChar *fieldName, Addr base, SizeT size )
1206 if ( !read )
1207 POST_MEM_WRITE( base, size );
1210 static
1211 void msghdr_foreachfield (
1212 ThreadId tid,
1213 const HChar *name,
1214 struct vki_msghdr *msg,
1215 UInt length,
1216 void (*foreach_func)( ThreadId, Bool, const HChar *, Addr, SizeT ),
1217 Bool rekv /* "recv" apparently shadows some header decl on OSX108 */
1220 HChar fieldName[VG_(strlen)(name) + 32]; // large enough.
1221 Addr a;
1222 SizeT s;
1224 if ( !msg )
1225 return;
1227 VG_(sprintf) ( fieldName, "(%s)", name );
1229 /* FIELDPAIR helps the compiler do one call to foreach_func
1230 for consecutive (no holes) fields. */
1231 #define FIELDPAIR(f1,f2) \
1232 if (offsetof(struct vki_msghdr, f1) + sizeof(msg->f1) \
1233 == offsetof(struct vki_msghdr, f2)) \
1234 s += sizeof(msg->f2); \
1235 else { \
1236 foreach_func (tid, True, fieldName, a, s); \
1237 a = (Addr)&msg->f2; \
1238 s = sizeof(msg->f2); \
1241 a = (Addr)&msg->msg_name;
1242 s = sizeof(msg->msg_name);
1243 FIELDPAIR(msg_name, msg_namelen);
1244 FIELDPAIR(msg_namelen, msg_iov);
1245 FIELDPAIR(msg_iov, msg_iovlen);
1246 FIELDPAIR(msg_iovlen, msg_control);
1247 FIELDPAIR(msg_control, msg_controllen);
1248 foreach_func ( tid, True, fieldName, a, s);
1249 #undef FIELDPAIR
1251 /* msg_flags is completely ignored for send_mesg, recv_mesg doesn't read
1252 the field, but does write to it. */
1253 if ( rekv )
1254 foreach_func ( tid, False, fieldName, (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) );
1256 if ( ML_(safe_to_deref)(&msg->msg_name, sizeof (void *))
1257 && msg->msg_name ) {
1258 VG_(sprintf) ( fieldName, "(%s.msg_name)", name );
1259 foreach_func ( tid, False, fieldName,
1260 (Addr)msg->msg_name, msg->msg_namelen );
1263 if ( ML_(safe_to_deref)(&msg->msg_iov, sizeof (void *))
1264 && msg->msg_iov ) {
1265 struct vki_iovec *iov = msg->msg_iov;
1266 UInt i;
1268 if (ML_(safe_to_deref)(&msg->msg_iovlen, sizeof (UInt))) {
1269 VG_(sprintf) ( fieldName, "(%s.msg_iov)", name );
1270 foreach_func ( tid, True, fieldName, (Addr)iov,
1271 msg->msg_iovlen * sizeof( struct vki_iovec ) );
1273 for ( i = 0; i < msg->msg_iovlen && length > 0; ++i, ++iov ) {
1274 if (ML_(safe_to_deref)(&iov->iov_len, sizeof (UInt))) {
1275 UInt iov_len = iov->iov_len <= length ? iov->iov_len : length;
1276 VG_(sprintf) ( fieldName, "(%s.msg_iov[%u])", name, i );
1277 foreach_func ( tid, False, fieldName,
1278 (Addr)iov->iov_base, iov_len );
1279 length = length - iov_len;
1285 if ( ML_(safe_to_deref) (&msg->msg_control, sizeof (void *))
1286 && msg->msg_control ) {
1287 VG_(sprintf) ( fieldName, "(%s.msg_control)", name );
1288 foreach_func ( tid, False, fieldName,
1289 (Addr)msg->msg_control, msg->msg_controllen );
1294 static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
1296 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
1298 while (cm) {
1299 if (cm->cmsg_level == VKI_SOL_SOCKET
1300 && cm->cmsg_type == VKI_SCM_RIGHTS ) {
1301 Int *fds = (Int *) VKI_CMSG_DATA(cm);
1302 Int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
1303 / sizeof(int);
1304 Int i;
1306 for (i = 0; i < fdc; i++)
1307 if(VG_(clo_track_fds))
1308 // XXX: must we check the range on these fds with
1309 // ML_(fd_allowed)()?
1310 ML_(record_fd_open_named)(tid, fds[i]);
1313 cm = VKI_CMSG_NXTHDR(msg, cm);
1317 /* GrP kernel ignores sa_len (at least on Darwin); this checks the rest */
1318 void ML_(pre_mem_read_sockaddr) ( ThreadId tid,
1319 const HChar *description,
1320 struct vki_sockaddr *sa, UInt salen )
1322 HChar outmsg[VG_(strlen)( description ) + 30]; // large enough
1323 struct vki_sockaddr_un* saun = (struct vki_sockaddr_un *)sa;
1324 struct vki_sockaddr_in* sin = (struct vki_sockaddr_in *)sa;
1325 struct vki_sockaddr_in6* sin6 = (struct vki_sockaddr_in6 *)sa;
1326 # ifdef VKI_AF_BLUETOOTH
1327 struct vki_sockaddr_rc* rc = (struct vki_sockaddr_rc *)sa;
1328 # endif
1329 # ifdef VKI_AF_NETLINK
1330 struct vki_sockaddr_nl* nl = (struct vki_sockaddr_nl *)sa;
1331 # endif
1333 /* NULL/zero-length sockaddrs are legal */
1334 if ( sa == NULL || salen == 0 ) return;
1336 VG_(sprintf) ( outmsg, description, "sa_family" );
1337 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
1338 #if defined(VGO_freebsd)
1339 VG_(sprintf) ( outmsg, description, "sa_len" );
1340 PRE_MEM_READ( outmsg, (Addr) &sa->sa_len, sizeof(char));
1341 #endif
1343 /* Don't do any extra checking if we cannot determine the sa_family. */
1344 if (! ML_(safe_to_deref) (&sa->sa_family, sizeof(vki_sa_family_t)))
1345 return;
1347 switch (sa->sa_family) {
1349 case VKI_AF_UNIX:
1350 if (ML_(safe_to_deref) (&saun->sun_path, sizeof (Addr))) {
1351 VG_(sprintf) ( outmsg, description, "sun_path" );
1352 PRE_MEM_RASCIIZ( outmsg, (Addr) saun->sun_path );
1353 // GrP fixme max of sun_len-2? what about nul char?
1355 break;
1357 case VKI_AF_INET:
1358 VG_(sprintf) ( outmsg, description, "sin_port" );
1359 PRE_MEM_READ( outmsg, (Addr) &sin->sin_port, sizeof (sin->sin_port) );
1360 VG_(sprintf) ( outmsg, description, "sin_addr" );
1361 PRE_MEM_READ( outmsg, (Addr) &sin->sin_addr, sizeof (sin->sin_addr) );
1362 break;
1364 case VKI_AF_INET6:
1365 VG_(sprintf) ( outmsg, description, "sin6_port" );
1366 PRE_MEM_READ( outmsg,
1367 (Addr) &sin6->sin6_port, sizeof (sin6->sin6_port) );
1368 VG_(sprintf) ( outmsg, description, "sin6_flowinfo" );
1369 PRE_MEM_READ( outmsg,
1370 (Addr) &sin6->sin6_flowinfo, sizeof (sin6->sin6_flowinfo) );
1371 VG_(sprintf) ( outmsg, description, "sin6_addr" );
1372 PRE_MEM_READ( outmsg,
1373 (Addr) &sin6->sin6_addr, sizeof (sin6->sin6_addr) );
1374 VG_(sprintf) ( outmsg, description, "sin6_scope_id" );
1375 PRE_MEM_READ( outmsg,
1376 (Addr) &sin6->sin6_scope_id, sizeof (sin6->sin6_scope_id) );
1377 break;
1379 # ifdef VKI_AF_BLUETOOTH
1380 case VKI_AF_BLUETOOTH:
1381 VG_(sprintf) ( outmsg, description, "rc_bdaddr" );
1382 PRE_MEM_READ( outmsg, (Addr) &rc->rc_bdaddr, sizeof (rc->rc_bdaddr) );
1383 VG_(sprintf) ( outmsg, description, "rc_channel" );
1384 PRE_MEM_READ( outmsg, (Addr) &rc->rc_channel, sizeof (rc->rc_channel) );
1385 break;
1386 # endif
1388 # ifdef VKI_AF_NETLINK
1389 case VKI_AF_NETLINK:
1390 VG_(sprintf)(outmsg, description, "nl_pid");
1391 PRE_MEM_READ(outmsg, (Addr)&nl->nl_pid, sizeof(nl->nl_pid));
1392 VG_(sprintf)(outmsg, description, "nl_groups");
1393 PRE_MEM_READ(outmsg, (Addr)&nl->nl_groups, sizeof(nl->nl_groups));
1394 break;
1395 # endif
1397 # ifdef VKI_AF_UNSPEC
1398 case VKI_AF_UNSPEC:
1399 break;
1400 # endif
1402 default:
1403 /* No specific information about this address family.
1404 Let's just check the full data following the family.
1405 Note that this can give false positive if this (unknown)
1406 struct sockaddr_???? has padding bytes between its elements. */
1407 VG_(sprintf) ( outmsg, description, "sa_data" );
1408 PRE_MEM_READ( outmsg, (Addr)&sa->sa_family + sizeof(sa->sa_family),
1409 salen - sizeof(sa->sa_family));
1410 break;
1414 /* Dereference a pointer to a UInt. */
1415 static UInt deref_UInt ( ThreadId tid, Addr a, const HChar* s )
1417 UInt* a_p = (UInt*)a;
1418 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
1419 if (a_p == NULL || ! ML_(safe_to_deref) (a_p, sizeof(UInt)))
1420 return 0;
1421 else
1422 return *a_p;
1425 void ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p,
1426 const HChar* buf_s, const HChar* buflen_s )
1428 if (VG_(tdict).track_pre_mem_write) {
1429 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
1430 if (buflen_in > 0) {
1431 VG_(tdict).track_pre_mem_write(
1432 Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
1437 void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res,
1438 Addr buf_p, Addr buflen_p, const HChar* s )
1440 if (!sr_isError(res) && VG_(tdict).track_post_mem_write) {
1441 UInt buflen_out = deref_UInt( tid, buflen_p, s);
1442 if (buflen_out > 0 && buf_p != (Addr)NULL) {
1443 VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
1448 /* ---------------------------------------------------------------------
1449 Data seg end, for brk()
1450 ------------------------------------------------------------------ */
1452 /* +--------+------------+
1453 | anon | resvn |
1454 +--------+------------+
1456 ^ ^ ^
1457 | | boundary is page aligned
1458 | VG_(brk_limit) -- no alignment constraint
1459 VG_(brk_base) -- page aligned -- does not move
1461 Both the anon part and the reservation part are always at least
1462 one page.
1465 /* Set the new data segment end to NEWBRK. If this succeeds, return
1466 NEWBRK, else return the current data segment end. */
1468 static Addr do_brk ( Addr newbrk, ThreadId tid )
1470 NSegment const* aseg;
1471 Addr newbrkP;
1472 SizeT delta;
1473 Bool debug = False;
1475 if (debug)
1476 VG_(printf)("\ndo_brk: brk_base=%#lx brk_limit=%#lx newbrk=%#lx\n",
1477 VG_(brk_base), VG_(brk_limit), newbrk);
1479 if (0) VG_(am_show_nsegments)(0, "in_brk");
1481 if (newbrk < VG_(brk_base))
1482 /* Clearly impossible. */
1483 goto bad;
1485 if (newbrk < VG_(brk_limit)) {
1486 /* shrinking the data segment. Be lazy and don't munmap the
1487 excess area. */
1488 NSegment const * seg = VG_(am_find_nsegment)(newbrk);
1489 vg_assert(seg);
1491 if (seg->hasT)
1492 VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk,
1493 "do_brk(shrink)" );
1494 /* Since we're being lazy and not unmapping pages, we have to
1495 zero out the area, so that if the area later comes back into
1496 circulation, it will be filled with zeroes, as if it really
1497 had been unmapped and later remapped. Be a bit paranoid and
1498 try hard to ensure we're not going to segfault by doing the
1499 write - check both ends of the range are in the same segment
1500 and that segment is writable. */
1501 NSegment const * seg2;
1503 seg2 = VG_(am_find_nsegment)( VG_(brk_limit) - 1 );
1504 vg_assert(seg2);
1506 if (seg == seg2 && seg->hasW)
1507 VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk );
1509 VG_(brk_limit) = newbrk;
1510 return newbrk;
1513 /* otherwise we're expanding the brk segment. */
1514 if (VG_(brk_limit) > VG_(brk_base))
1515 aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
1516 else
1517 aseg = VG_(am_find_nsegment)( VG_(brk_limit) );
1519 /* These should be assured by setup_client_dataseg in m_main. */
1520 vg_assert(aseg);
1521 vg_assert(aseg->kind == SkAnonC);
1523 if (newbrk <= aseg->end + 1) {
1524 /* still fits within the anon segment. */
1525 VG_(brk_limit) = newbrk;
1526 return newbrk;
1529 newbrkP = VG_PGROUNDUP(newbrk);
1530 delta = newbrkP - (aseg->end + 1);
1531 vg_assert(delta > 0);
1532 vg_assert(VG_IS_PAGE_ALIGNED(delta));
1534 Bool overflow = False;
1535 if (! VG_(am_extend_into_adjacent_reservation_client)( aseg->start, delta,
1536 &overflow)) {
1537 if (overflow) {
1538 static Bool alreadyComplained = False;
1539 if (!alreadyComplained) {
1540 alreadyComplained = True;
1541 if (VG_(clo_verbosity) > 0) {
1542 VG_(umsg)("brk segment overflow in thread #%u: "
1543 "can't grow to %#lx\n",
1544 tid, newbrkP);
1545 VG_(umsg)("(see section Limitations in user manual)\n");
1546 VG_(umsg)("NOTE: further instances of this message "
1547 "will not be shown\n");
1550 } else {
1551 if (VG_(clo_verbosity) > 0) {
1552 VG_(umsg)("Cannot map memory to grow brk segment in thread #%u "
1553 "to %#lx\n", tid, newbrkP);
1554 VG_(umsg)("(see section Limitations in user manual)\n");
1557 goto bad;
1560 VG_(brk_limit) = newbrk;
1561 return newbrk;
1563 bad:
1564 return VG_(brk_limit);
1568 /* ---------------------------------------------------------------------
1569 Vet file descriptors for sanity
1570 ------------------------------------------------------------------ */
1572 > - what does the "Bool soft" parameter mean?
1574 (Tom Hughes, 3 Oct 05):
1576 Whether or not to consider a file descriptor invalid if it is above
1577 the current soft limit.
1579 Basically if we are testing whether a newly created file descriptor is
1580 valid (in a post handler) then we set soft to true, and if we are
1581 testing whether a file descriptor that is about to be used (in a pre
1582 handler) is valid [viz, an already-existing fd] then we set it to false.
1584 The point is that if the (virtual) soft limit is lowered then any
1585 existing descriptors can still be read/written/closed etc (so long as
1586 they are below the valgrind reserved descriptors) but no new
1587 descriptors can be created above the new soft limit.
1589 (jrs 4 Oct 05: in which case, I've renamed it "isNewFd")
1592 /* Return true if we're allowed to use or create this fd */
1593 Bool ML_(fd_allowed)(Int fd, const HChar *syscallname, ThreadId tid,
1594 Bool isNewFd)
1596 Bool allowed = True;
1598 /* hard limits always apply */
1599 if (fd < 0 || fd >= VG_(fd_hard_limit))
1600 allowed = False;
1602 /* hijacking the output fds is never allowed */
1603 if (fd == VG_(log_output_sink).fd || fd == VG_(xml_output_sink).fd)
1604 allowed = False;
1606 /* if creating a new fd (rather than using an existing one), the
1607 soft limit must also be observed */
1608 if (isNewFd && fd >= VG_(fd_soft_limit))
1609 allowed = False;
1611 /* this looks like it ought to be included, but causes problems: */
1613 if (fd == 2 && VG_(debugLog_getLevel)() > 0)
1614 allowed = False;
1616 /* The difficulty is as follows: consider a program P which expects
1617 to be able to mess with (redirect) its own stderr (fd 2).
1618 Usually to deal with P we would issue command line flags to send
1619 logging somewhere other than stderr, so as not to disrupt P.
1620 The problem is that -d unilaterally hijacks stderr with no
1621 consultation with P. And so, if this check is enabled, P will
1622 work OK normally but fail if -d is issued.
1624 Basically -d is a hack and you take your chances when using it.
1625 It's very useful for low level debugging -- particularly at
1626 startup -- and having its presence change the behaviour of the
1627 client is exactly what we don't want. */
1629 /* croak? */
1630 if ((!allowed) && VG_(showing_core_errors)() ) {
1631 VG_(message)(Vg_UserMsg,
1632 "Warning: invalid file descriptor %d in syscall %s()\n",
1633 fd, syscallname);
1634 if (fd == VG_(log_output_sink).fd && VG_(log_output_sink).fd >= 0)
1635 VG_(message)(Vg_UserMsg,
1636 " Use --log-fd=<number> to select an alternative log fd.\n");
1637 if (fd == VG_(xml_output_sink).fd && VG_(xml_output_sink).fd >= 0)
1638 VG_(message)(Vg_UserMsg,
1639 " Use --xml-fd=<number> to select an alternative XML "
1640 "output fd.\n");
1641 // DDD: consider always printing this stack trace, it's useful.
1642 // Also consider also making this a proper core error, ie.
1643 // suppressible and all that.
1644 if (VG_(clo_verbosity) > 1) {
1645 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
1649 return allowed;
1653 /* ---------------------------------------------------------------------
1654 Deal with a bunch of socket-related syscalls
1655 ------------------------------------------------------------------ */
1657 /* ------ */
1659 void
1660 ML_(generic_PRE_sys_socketpair) ( ThreadId tid,
1661 UWord arg0, UWord arg1,
1662 UWord arg2, UWord arg3 )
1664 /* int socketpair(int d, int type, int protocol, int sv[2]); */
1665 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
1666 arg3, 2*sizeof(int) );
1669 SysRes
1670 ML_(generic_POST_sys_socketpair) ( ThreadId tid,
1671 SysRes res,
1672 UWord arg0, UWord arg1,
1673 UWord arg2, UWord arg3 )
1675 SysRes r = res;
1676 Int fd1 = ((Int*)arg3)[0];
1677 Int fd2 = ((Int*)arg3)[1];
1678 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1679 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1680 if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
1681 !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
1682 VG_(close)(fd1);
1683 VG_(close)(fd2);
1684 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1685 } else {
1686 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1687 if (VG_(clo_track_fds)) {
1688 ML_(record_fd_open_nameless)(tid, fd1);
1689 ML_(record_fd_open_nameless)(tid, fd2);
1692 return r;
1695 /* ------ */
1697 SysRes
1698 ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
1700 SysRes r = res;
1701 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1702 if (!ML_(fd_allowed)(sr_Res(res), "socket", tid, True)) {
1703 VG_(close)(sr_Res(res));
1704 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1705 } else {
1706 if (VG_(clo_track_fds))
1707 ML_(record_fd_open_nameless)(tid, sr_Res(res));
1709 return r;
1712 /* ------ */
1714 void
1715 ML_(generic_PRE_sys_bind) ( ThreadId tid,
1716 UWord arg0, UWord arg1, UWord arg2 )
1718 /* int bind(int sockfd, struct sockaddr *my_addr,
1719 int addrlen); */
1720 ML_(pre_mem_read_sockaddr) (
1721 tid, "socketcall.bind(my_addr.%s)",
1722 (struct vki_sockaddr *) arg1, arg2
1726 /* ------ */
1728 void
1729 ML_(generic_PRE_sys_accept) ( ThreadId tid,
1730 UWord arg0, UWord arg1, UWord arg2 )
1732 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1733 Addr addr_p = arg1;
1734 Addr addrlen_p = arg2;
1735 if (addr_p != (Addr)NULL)
1736 ML_(buf_and_len_pre_check) ( tid, addr_p, addrlen_p,
1737 "socketcall.accept(addr)",
1738 "socketcall.accept(addrlen_in)" );
1741 SysRes
1742 ML_(generic_POST_sys_accept) ( ThreadId tid,
1743 SysRes res,
1744 UWord arg0, UWord arg1, UWord arg2 )
1746 SysRes r = res;
1747 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1748 if (!ML_(fd_allowed)(sr_Res(res), "accept", tid, True)) {
1749 VG_(close)(sr_Res(res));
1750 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1751 } else {
1752 Addr addr_p = arg1;
1753 Addr addrlen_p = arg2;
1754 if (addr_p != (Addr)NULL)
1755 ML_(buf_and_len_post_check) ( tid, res, addr_p, addrlen_p,
1756 "socketcall.accept(addrlen_out)" );
1757 if (VG_(clo_track_fds))
1758 ML_(record_fd_open_nameless)(tid, sr_Res(res));
1760 return r;
1763 /* ------ */
1765 void
1766 ML_(generic_PRE_sys_sendto) ( ThreadId tid,
1767 UWord arg0, UWord arg1, UWord arg2,
1768 UWord arg3, UWord arg4, UWord arg5 )
1770 /* int sendto(int s, const void *msg, int len,
1771 unsigned int flags,
1772 const struct sockaddr *to, int tolen); */
1773 PRE_MEM_READ( "socketcall.sendto(msg)",
1774 arg1, /* msg */
1775 arg2 /* len */ );
1776 ML_(pre_mem_read_sockaddr) (
1777 tid, "socketcall.sendto(to.%s)",
1778 (struct vki_sockaddr *) arg4, arg5
1782 /* ------ */
1784 void
1785 ML_(generic_PRE_sys_send) ( ThreadId tid,
1786 UWord arg0, UWord arg1, UWord arg2 )
1788 /* int send(int s, const void *msg, size_t len, int flags); */
1789 PRE_MEM_READ( "socketcall.send(msg)",
1790 arg1, /* msg */
1791 arg2 /* len */ );
1795 /* ------ */
1797 void
1798 ML_(generic_PRE_sys_recvfrom) ( ThreadId tid,
1799 UWord arg0, UWord arg1, UWord arg2,
1800 UWord arg3, UWord arg4, UWord arg5 )
1802 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1803 struct sockaddr *from, int *fromlen); */
1804 Addr buf_p = arg1;
1805 Int len = arg2;
1806 Addr from_p = arg4;
1807 Addr fromlen_p = arg5;
1808 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1809 if (from_p != (Addr)NULL)
1810 ML_(buf_and_len_pre_check) ( tid, from_p, fromlen_p,
1811 "socketcall.recvfrom(from)",
1812 "socketcall.recvfrom(fromlen_in)" );
1815 void
1816 ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
1817 SysRes res,
1818 UWord arg0, UWord arg1, UWord arg2,
1819 UWord arg3, UWord arg4, UWord arg5 )
1821 Addr buf_p = arg1;
1822 Int len = arg2;
1823 Addr from_p = arg4;
1824 Addr fromlen_p = arg5;
1826 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1827 if (from_p != (Addr)NULL)
1828 ML_(buf_and_len_post_check) ( tid, res, from_p, fromlen_p,
1829 "socketcall.recvfrom(fromlen_out)" );
1830 POST_MEM_WRITE( buf_p, len );
1833 /* ------ */
1835 void
1836 ML_(generic_PRE_sys_recv) ( ThreadId tid,
1837 UWord arg0, UWord arg1, UWord arg2 )
1839 /* int recv(int s, void *buf, int len, unsigned int flags); */
1840 /* man 2 recv says:
1841 The recv call is normally used only on a connected socket
1842 (see connect(2)) and is identical to recvfrom with a NULL
1843 from parameter.
1845 PRE_MEM_WRITE( "socketcall.recv(buf)",
1846 arg1, /* buf */
1847 arg2 /* len */ );
1850 void
1851 ML_(generic_POST_sys_recv) ( ThreadId tid,
1852 UWord res,
1853 UWord arg0, UWord arg1, UWord arg2 )
1855 if (arg1 != 0) {
1856 POST_MEM_WRITE( arg1, /* buf */
1857 arg2 /* len */ );
1861 /* ------ */
1863 void
1864 ML_(generic_PRE_sys_connect) ( ThreadId tid,
1865 UWord arg0, UWord arg1, UWord arg2 )
1867 /* int connect(int sockfd,
1868 struct sockaddr *serv_addr, int addrlen ); */
1869 ML_(pre_mem_read_sockaddr) ( tid,
1870 "socketcall.connect(serv_addr.%s)",
1871 (struct vki_sockaddr *) arg1, arg2);
1874 /* ------ */
1876 void
1877 ML_(generic_PRE_sys_setsockopt) ( ThreadId tid,
1878 UWord arg0, UWord arg1, UWord arg2,
1879 UWord arg3, UWord arg4 )
1881 /* int setsockopt(int s, int level, int optname,
1882 const void *optval, int optlen); */
1883 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1884 arg3, /* optval */
1885 arg4 /* optlen */ );
1888 /* ------ */
1890 void
1891 ML_(generic_PRE_sys_getsockname) ( ThreadId tid,
1892 UWord arg0, UWord arg1, UWord arg2 )
1894 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1895 Addr name_p = arg1;
1896 Addr namelen_p = arg2;
1897 /* Nb: name_p cannot be NULL */
1898 ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p,
1899 "socketcall.getsockname(name)",
1900 "socketcall.getsockname(namelen_in)" );
1903 void
1904 ML_(generic_POST_sys_getsockname) ( ThreadId tid,
1905 SysRes res,
1906 UWord arg0, UWord arg1, UWord arg2 )
1908 Addr name_p = arg1;
1909 Addr namelen_p = arg2;
1910 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1911 ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
1912 "socketcall.getsockname(namelen_out)" );
1915 /* ------ */
1917 void
1918 ML_(generic_PRE_sys_getpeername) ( ThreadId tid,
1919 UWord arg0, UWord arg1, UWord arg2 )
1921 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1922 Addr name_p = arg1;
1923 Addr namelen_p = arg2;
1924 /* Nb: name_p cannot be NULL */
1925 ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p,
1926 "socketcall.getpeername(name)",
1927 "socketcall.getpeername(namelen_in)" );
1930 void
1931 ML_(generic_POST_sys_getpeername) ( ThreadId tid,
1932 SysRes res,
1933 UWord arg0, UWord arg1, UWord arg2 )
1935 Addr name_p = arg1;
1936 Addr namelen_p = arg2;
1937 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1938 ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
1939 "socketcall.getpeername(namelen_out)" );
1942 /* ------ */
1944 void
1945 ML_(generic_PRE_sys_sendmsg) ( ThreadId tid, const HChar *name,
1946 struct vki_msghdr *msg )
1948 msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_read_sendmsg, False );
1951 /* ------ */
1953 void
1954 ML_(generic_PRE_sys_recvmsg) ( ThreadId tid, const HChar *name,
1955 struct vki_msghdr *msg )
1957 msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_write_recvmsg, True );
1960 void
1961 ML_(generic_POST_sys_recvmsg) ( ThreadId tid, const HChar *name,
1962 struct vki_msghdr *msg, UInt length )
1964 msghdr_foreachfield( tid, name, msg, length, post_mem_write_recvmsg, True );
1965 check_cmsg_for_fds( tid, msg );
1969 /* ---------------------------------------------------------------------
1970 Deal with a bunch of IPC related syscalls
1971 ------------------------------------------------------------------ */
1973 /* ------ */
1975 void
1976 ML_(generic_PRE_sys_semop) ( ThreadId tid,
1977 UWord arg0, UWord arg1, UWord arg2 )
1979 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
1980 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1983 /* ------ */
1985 void
1986 ML_(generic_PRE_sys_semtimedop) ( ThreadId tid,
1987 UWord arg0, UWord arg1,
1988 UWord arg2, UWord arg3 )
1990 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
1991 struct timespec *timeout); */
1992 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
1993 if (arg3 != 0)
1994 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
1997 /* ------ */
1999 static
2000 UInt get_sem_count( Int semid )
2002 union vki_semun arg;
2003 SysRes res;
2005 # if defined(__NR_semctl)
2006 # if defined(VGO_darwin)
2007 /* Darwin has no specific 64 bit semid_ds, but has __NR_semctl. */
2008 struct vki_semid_ds buf;
2009 arg.buf = &buf;
2010 # else
2011 struct vki_semid64_ds buf;
2012 arg.buf64 = &buf;
2013 # endif
2014 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
2015 if (sr_isError(res))
2016 return 0;
2018 return buf.sem_nsems;
2019 # elif defined(__NR___semctl) /* FreeBSD */
2020 struct vki_semid_ds buf;
2021 arg.buf = &buf;
2022 res = VG_(do_syscall4)(__NR___semctl, semid, 0, VKI_IPC_STAT, (RegWord)&arg);
2024 if (sr_isError(res))
2025 return 0;
2027 // both clang-tidy and coverity complain about this but I think they are both wrong
2028 return buf.sem_nsems;
2029 # elif defined(__NR_semsys) /* Solaris */
2030 struct vki_semid_ds buf;
2031 arg.buf = &buf;
2032 res = VG_(do_syscall5)(__NR_semsys, VKI_SEMCTL, semid, 0, VKI_IPC_STAT,
2033 *(UWord *)&arg);
2034 if (sr_isError(res))
2035 return 0;
2037 return buf.sem_nsems;
2039 # else
2040 struct vki_semid_ds buf;
2041 arg.buf = &buf;
2042 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
2043 VKI_IPC_STAT, (UWord)&arg);
2044 if (sr_isError(res))
2045 return 0;
2047 return buf.sem_nsems;
2048 # endif
2051 void
2052 ML_(generic_PRE_sys_semctl) ( ThreadId tid,
2053 UWord arg0, UWord arg1,
2054 UWord arg2, UWord arg3 )
2056 /* int semctl(int semid, int semnum, int cmd, ...); */
2057 union vki_semun arg = *(union vki_semun *)&arg3;
2058 UInt nsems;
2059 switch (arg2 /* cmd */) {
2060 #if defined(VKI_IPC_INFO)
2061 case VKI_IPC_INFO:
2062 case VKI_SEM_INFO:
2063 #if defined(VKI_IPC_64)
2064 case VKI_IPC_INFO|VKI_IPC_64:
2065 case VKI_SEM_INFO|VKI_IPC_64:
2066 #endif
2067 #if defined(VGO_freebsd)
2068 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
2069 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2070 #else
2071 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
2072 (Addr)arg.buf, sizeof(struct vki_seminfo) );
2073 #endif
2074 break;
2075 #endif
2077 case VKI_IPC_STAT:
2078 #if defined(VKI_SEM_STAT)
2079 case VKI_SEM_STAT:
2080 #endif
2081 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
2082 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2083 break;
2085 #if defined(VKI_IPC_64)
2086 case VKI_IPC_STAT|VKI_IPC_64:
2087 #if defined(VKI_SEM_STAT)
2088 case VKI_SEM_STAT|VKI_IPC_64:
2089 #endif
2090 #endif
2091 #if defined(VKI_IPC_STAT64)
2092 case VKI_IPC_STAT64:
2093 #endif
2094 #if defined(VKI_IPC_64) || defined(VKI_IPC_STAT64)
2095 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
2096 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2097 break;
2098 #endif
2100 case VKI_IPC_SET:
2101 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
2102 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2103 break;
2105 #if defined(VKI_IPC_64)
2106 case VKI_IPC_SET|VKI_IPC_64:
2107 #endif
2108 #if defined(VKI_IPC_SET64)
2109 case VKI_IPC_SET64:
2110 #endif
2111 #if defined(VKI_IPC64) || defined(VKI_IPC_SET64)
2112 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
2113 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2114 break;
2115 #endif
2117 case VKI_GETALL:
2118 #if defined(VKI_IPC_64)
2119 case VKI_GETALL|VKI_IPC_64:
2120 #endif
2121 nsems = get_sem_count( arg0 );
2122 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
2123 (Addr)arg.array, sizeof(unsigned short) * nsems );
2124 break;
2126 case VKI_SETALL:
2127 #if defined(VKI_IPC_64)
2128 case VKI_SETALL|VKI_IPC_64:
2129 #endif
2130 nsems = get_sem_count( arg0 );
2131 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
2132 (Addr)arg.array, sizeof(unsigned short) * nsems );
2133 break;
2137 void
2138 ML_(generic_POST_sys_semctl) ( ThreadId tid,
2139 UWord res,
2140 UWord arg0, UWord arg1,
2141 UWord arg2, UWord arg3 )
2143 union vki_semun arg = *(union vki_semun *)&arg3;
2144 UInt nsems;
2145 switch (arg2 /* cmd */) {
2146 #if defined(VKI_IPC_INFO)
2147 case VKI_IPC_INFO:
2148 case VKI_SEM_INFO:
2149 #if defined(VKI_IPC_64)
2150 case VKI_IPC_INFO|VKI_IPC_64:
2151 case VKI_SEM_INFO|VKI_IPC_64:
2152 #endif
2153 #if defined(VGO_freebsd)
2154 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2155 #else
2156 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
2157 #endif
2158 break;
2159 #endif
2161 case VKI_IPC_STAT:
2162 #if defined(VKI_SEM_STAT)
2163 case VKI_SEM_STAT:
2164 #endif
2165 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2166 break;
2168 #if defined(VKI_IPC_64)
2169 case VKI_IPC_STAT|VKI_IPC_64:
2170 case VKI_SEM_STAT|VKI_IPC_64:
2171 #endif
2172 #if defined(VKI_IPC_STAT64)
2173 case VKI_IPC_STAT64:
2174 #endif
2175 #if defined(VKI_IPC_64) || defined(VKI_IPC_STAT64)
2176 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2177 break;
2178 #endif
2180 case VKI_GETALL:
2181 #if defined(VKI_IPC_64)
2182 case VKI_GETALL|VKI_IPC_64:
2183 #endif
2184 nsems = get_sem_count( arg0 );
2185 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
2186 break;
2190 /* ------ */
2192 /* ------ */
2194 static
2195 SizeT get_shm_size ( Int shmid )
2198 * The excluded platforms below gained direct shmctl in Linux 5.1. Keep
2199 * using ipc-multiplexed shmctl to keep compatibility with older kernel
2200 * versions.
2202 #if defined(__NR_shmctl) && \
2203 !defined(VGP_x86_linux) && !defined(VGP_mips32_linux) && \
2204 !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) && \
2205 !defined(VGP_ppc64le_linux) && !defined(VGP_s390x_linux)
2206 # ifdef VKI_IPC_64
2207 struct vki_shmid64_ds buf;
2209 * On Linux, the following ABIs use old shmid_ds by default with direct
2210 * shmctl and require IPC_64 for shmid64_ds (i.e. the direct syscall is
2211 * mapped to sys_old_shmctl):
2212 * alpha, arm, microblaze, mips n32/n64, xtensa
2213 * Other Linux ABIs use shmid64_ds by default and do not recognize IPC_64
2214 * with the direct shmctl syscall (but still recognize it for the
2215 * ipc-multiplexed version if that exists for the ABI).
2217 # if defined(VGO_linux) && !defined(VGP_arm_linux) && !defined(VGP_mips64_linux)
2218 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid,
2219 VKI_IPC_STAT, (UWord)&buf);
2220 # else
2221 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid,
2222 VKI_IPC_STAT|VKI_IPC_64, (UWord)&buf);
2223 # endif
2224 # else /* !def VKI_IPC_64 */
2225 struct vki_shmid_ds buf;
2226 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
2227 # endif /* def VKI_IPC_64 */
2228 #elif defined(__NR_shmsys) /* Solaris */
2229 struct vki_shmid_ds buf;
2230 SysRes __res = VG_(do_syscall4)(__NR_shmsys, VKI_SHMCTL, shmid, VKI_IPC_STAT,
2231 (UWord)&buf);
2232 #else
2233 struct vki_shmid_ds buf;
2234 SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
2235 VKI_IPC_STAT, 0, (UWord)&buf);
2236 #endif
2237 if (sr_isError(__res))
2238 return 0;
2240 return (SizeT) buf.shm_segsz;
2243 UWord
2244 ML_(generic_PRE_sys_shmat) ( ThreadId tid,
2245 UWord arg0, UWord arg1, UWord arg2 )
2247 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
2248 SizeT segmentSize = get_shm_size ( arg0 );
2249 UWord tmp;
2250 Bool ok;
2251 if (arg1 == 0) {
2252 /* arm-linux only: work around the fact that
2253 VG_(am_get_advisory_client_simple) produces something that is
2254 VKI_PAGE_SIZE aligned, whereas what we want is something
2255 VKI_SHMLBA aligned, and VKI_SHMLBA >= VKI_PAGE_SIZE. Hence
2256 increase the request size by VKI_SHMLBA - VKI_PAGE_SIZE and
2257 then round the result up to the next VKI_SHMLBA boundary.
2258 See bug 222545 comment 15. So far, arm-linux is the only
2259 platform where this is known to be necessary. */
2260 vg_assert(VKI_SHMLBA >= VKI_PAGE_SIZE);
2261 if (VKI_SHMLBA > VKI_PAGE_SIZE) {
2262 segmentSize += VKI_SHMLBA - VKI_PAGE_SIZE;
2264 tmp = VG_(am_get_advisory_client_simple)(0, segmentSize, &ok);
2265 if (ok) {
2266 if (VKI_SHMLBA > VKI_PAGE_SIZE) {
2267 arg1 = VG_ROUNDUP(tmp, VKI_SHMLBA);
2268 } else {
2269 arg1 = tmp;
2273 else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
2274 arg1 = 0;
2275 return arg1;
2278 void
2279 ML_(generic_POST_sys_shmat) ( ThreadId tid,
2280 UWord res,
2281 UWord arg0, UWord arg1, UWord arg2 )
2283 SizeT segmentSize = VG_PGROUNDUP(get_shm_size(arg0));
2284 if ( segmentSize > 0 ) {
2285 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
2286 Bool d;
2288 if (arg2 & VKI_SHM_RDONLY)
2289 prot &= ~VKI_PROT_WRITE;
2290 /* It isn't exactly correct to pass 0 for the fd and offset
2291 here. The kernel seems to think the corresponding section
2292 does have dev/ino numbers:
2294 04e52000-04ec8000 rw-s 00000000 00:06 1966090 /SYSV00000000 (deleted)
2296 However there is no obvious way to find them. In order to
2297 cope with the discrepancy, aspacem's sync checker omits the
2298 dev/ino correspondence check in cases where V does not know
2299 the dev/ino. */
2300 d = VG_(am_notify_client_shmat)( res, segmentSize, prot );
2302 /* we don't distinguish whether it's read-only or
2303 * read-write -- it doesn't matter really. */
2304 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False,
2305 0/*di_handle*/ );
2306 if (d)
2307 VG_(discard_translations)( (Addr)res,
2308 (ULong)VG_PGROUNDUP(segmentSize),
2309 "ML_(generic_POST_sys_shmat)" );
2313 /* ------ */
2315 Bool
2316 ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
2318 /* int shmdt(const void *shmaddr); */
2319 return ML_(valid_client_addr)(arg0, 1, tid, "shmdt");
2322 void
2323 ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
2325 NSegment const* s = VG_(am_find_nsegment)(arg0);
2327 if (s != NULL) {
2328 Addr s_start = s->start;
2329 SizeT s_len = s->end+1 - s->start;
2330 Bool d;
2332 vg_assert(s->kind == SkShmC);
2333 vg_assert(s->start == arg0);
2335 d = VG_(am_notify_munmap)(s_start, s_len);
2336 s = NULL; /* s is now invalid */
2337 VG_TRACK( die_mem_munmap, s_start, s_len );
2338 if (d)
2339 VG_(discard_translations)( s_start,
2340 (ULong)s_len,
2341 "ML_(generic_POST_sys_shmdt)" );
2344 /* ------ */
2346 void
2347 ML_(generic_PRE_sys_shmctl) ( ThreadId tid,
2348 UWord arg0, UWord arg1, UWord arg2 )
2350 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
2351 switch (arg1 /* cmd */) {
2352 #if defined(VKI_IPC_INFO)
2353 case VKI_IPC_INFO:
2354 # if defined(VGO_freebsd)
2355 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2356 arg2, sizeof(struct vki_shmid_ds) );
2357 # else
2358 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2359 arg2, sizeof(struct vki_shminfo) );
2360 # endif
2361 break;
2362 #if defined(VKI_IPC_64)
2363 case VKI_IPC_INFO|VKI_IPC_64:
2364 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2365 arg2, sizeof(struct vki_shminfo64) );
2366 break;
2367 #endif
2368 #endif
2370 #if defined(VKI_SHM_INFO)
2371 case VKI_SHM_INFO:
2372 #if defined(VKI_IPC_64)
2373 case VKI_SHM_INFO|VKI_IPC_64:
2374 #endif
2375 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
2376 arg2, sizeof(struct vki_shm_info) );
2377 break;
2378 #endif
2380 case VKI_IPC_STAT:
2381 #if defined(VKI_SHM_STAT)
2382 case VKI_SHM_STAT:
2383 #endif
2384 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
2385 arg2, sizeof(struct vki_shmid_ds) );
2386 break;
2388 #if defined(VKI_IPC_64)
2389 case VKI_IPC_STAT|VKI_IPC_64:
2390 case VKI_SHM_STAT|VKI_IPC_64:
2391 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
2392 arg2, sizeof(struct vki_shmid64_ds) );
2393 break;
2394 #endif
2396 case VKI_IPC_SET:
2397 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
2398 arg2, sizeof(struct vki_shmid_ds) );
2399 break;
2401 #if defined(VKI_IPC_64)
2402 case VKI_IPC_SET|VKI_IPC_64:
2403 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
2404 arg2, sizeof(struct vki_shmid64_ds) );
2405 break;
2406 #endif
2410 void
2411 ML_(generic_POST_sys_shmctl) ( ThreadId tid,
2412 UWord res,
2413 UWord arg0, UWord arg1, UWord arg2 )
2415 switch (arg1 /* cmd */) {
2416 #if defined(VKI_IPC_INFO)
2417 case VKI_IPC_INFO:
2418 # if defined(VGO_freebsd)
2419 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
2420 # else
2421 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
2422 # endif
2423 break;
2424 #if defined(VKI_IPC_64)
2425 case VKI_IPC_INFO|VKI_IPC_64:
2426 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
2427 break;
2428 #endif
2429 #endif
2431 #if defined(VKI_SHM_INFO)
2432 case VKI_SHM_INFO:
2433 case VKI_SHM_INFO|VKI_IPC_64:
2434 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
2435 break;
2436 #endif
2438 case VKI_IPC_STAT:
2439 #if defined(VKI_SHM_STAT)
2440 case VKI_SHM_STAT:
2441 #endif
2442 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
2443 break;
2445 #if defined(VKI_IPC_64)
2446 case VKI_IPC_STAT|VKI_IPC_64:
2447 case VKI_SHM_STAT|VKI_IPC_64:
2448 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
2449 break;
2450 #endif
2456 /* ---------------------------------------------------------------------
2457 Generic handler for mmap
2458 ------------------------------------------------------------------ */
2461 * Although mmap is specified by POSIX and the argument are generally
2462 * consistent across platforms the precise details of the low level
2463 * argument passing conventions differ. For example:
2465 * - On x86-linux there is mmap (aka old_mmap) which takes the
2466 * arguments in a memory block and the offset in bytes; and
2467 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
2468 * way and the offset in pages.
2470 * - On ppc32-linux there is mmap (aka sys_mmap) which takes the
2471 * arguments in the normal way and the offset in bytes; and
2472 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
2473 * way and the offset in pages.
2475 * - On amd64-linux everything is simple and there is just the one
2476 * call, mmap (aka sys_mmap) which takes the arguments in the
2477 * normal way and the offset in bytes.
2479 * - On s390x-linux there is mmap (aka old_mmap) which takes the
2480 * arguments in a memory block and the offset in bytes. mmap2
2481 * is also available (but not exported via unistd.h) with
2482 * arguments in a memory block and the offset in pages.
2484 * To cope with all this we provide a generic handler function here
2485 * and then each platform implements one or more system call handlers
2486 * which call this generic routine after extracting and normalising
2487 * the arguments.
2490 SysRes
2491 ML_(generic_PRE_sys_mmap) ( ThreadId tid,
2492 UWord arg1, UWord arg2, UWord arg3,
2493 UWord arg4, UWord arg5, Off64T arg6 )
2495 Addr advised;
2496 SysRes sres;
2497 MapRequest mreq;
2498 Bool mreq_ok;
2500 # if defined(VGO_darwin)
2501 // Nb: we can't use this on Darwin, it has races:
2502 // * needs to RETRY if advisory succeeds but map fails
2503 // (could have been some other thread in a nonblocking call)
2504 // * needs to not use fixed-position mmap() on Darwin
2505 // (mmap will cheerfully smash whatever's already there, which might
2506 // be a new mapping from some other thread in a nonblocking call)
2507 VG_(core_panic)("can't use ML_(generic_PRE_sys_mmap) on Darwin");
2508 # endif
2510 if (arg2 == 0) {
2511 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
2512 shall be established. */
2513 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2516 if (!VG_IS_PAGE_ALIGNED(arg1)) {
2517 /* zap any misaligned addresses. */
2518 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
2519 to fail. Here, we catch them all. */
2520 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2523 if (!VG_IS_PAGE_ALIGNED(arg6)) {
2524 /* zap any misaligned offsets. */
2525 /* SuSV3 says: The off argument is constrained to be aligned and
2526 sized according to the value returned by sysconf() when
2527 passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
2528 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2531 /* Figure out what kind of allocation constraints there are
2532 (fixed/hint/any), and ask aspacem what we should do. */
2533 mreq.start = arg1;
2534 mreq.len = arg2;
2535 if (arg4 & VKI_MAP_FIXED) {
2536 mreq.rkind = MFixed;
2537 } else
2538 #if defined(VKI_MAP_ALIGN) /* Solaris specific */
2539 if (arg4 & VKI_MAP_ALIGN) {
2540 mreq.rkind = MAlign;
2541 if (mreq.start == 0) {
2542 mreq.start = VKI_PAGE_SIZE;
2544 /* VKI_MAP_FIXED and VKI_MAP_ALIGN don't like each other. */
2545 arg4 &= ~VKI_MAP_ALIGN;
2546 } else
2547 #endif
2548 if (arg1 != 0) {
2549 mreq.rkind = MHint;
2550 } else {
2551 mreq.rkind = MAny;
2554 /* Enquire ... */
2555 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2556 if (!mreq_ok) {
2557 /* Our request was bounced, so we'd better fail. */
2558 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2561 # if defined(VKI_MAP_32BIT)
2562 /* MAP_32BIT is royally unportable, so if the client asks for it, try our
2563 best to make it work (but without complexifying aspacemgr).
2564 If the user requested MAP_32BIT, the mmap-ed space must be in the
2565 first 2GB of the address space. So, return ENOMEM if aspacemgr
2566 advisory is above the first 2GB. If MAP_FIXED is also requested,
2567 MAP_32BIT has to be ignored.
2568 Assumption about aspacemgr behaviour: aspacemgr scans the address space
2569 from low addresses to find a free segment. No special effort is done
2570 to keep the first 2GB 'free' for this MAP_32BIT. So, this will often
2571 fail once the program has already allocated significant memory. */
2572 if ((arg4 & VKI_MAP_32BIT) && !(arg4 & VKI_MAP_FIXED)) {
2573 if (advised + arg2 >= 0x80000000)
2574 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
2576 # endif
2578 /* Otherwise we're OK (so far). Install aspacem's choice of
2579 address, and let the mmap go through. */
2580 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2581 arg4 | VKI_MAP_FIXED,
2582 arg5, arg6);
2584 # if defined(VKI_MAP_32BIT)
2585 /* No recovery trial if the advisory was not accepted. */
2586 if ((arg4 & VKI_MAP_32BIT) && !(arg4 & VKI_MAP_FIXED)
2587 && sr_isError(sres)) {
2588 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
2590 # endif
2592 /* A refinement: it may be that the kernel refused aspacem's choice
2593 of address. If we were originally asked for a hinted mapping,
2594 there is still a last chance: try again at any address.
2595 Hence: */
2596 if (mreq.rkind == MHint && sr_isError(sres)) {
2597 mreq.start = 0;
2598 mreq.len = arg2;
2599 mreq.rkind = MAny;
2600 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2601 if (!mreq_ok) {
2602 /* Our request was bounced, so we'd better fail. */
2603 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2605 /* and try again with the kernel */
2606 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2607 arg4 | VKI_MAP_FIXED,
2608 arg5, arg6);
2611 /* Yet another refinement : sometimes valgrind chooses an address
2612 which is not acceptable by the kernel. This at least happens
2613 when mmap-ing huge pages, using the flag MAP_HUGETLB.
2614 valgrind aspacem does not know about huge pages, and modifying
2615 it to handle huge pages is not straightforward (e.g. need
2616 to understand special file system mount options).
2617 So, let's just redo an mmap, without giving any constraint to
2618 the kernel. If that succeeds, check with aspacem that the returned
2619 address is acceptable.
2620 This will give a similar effect as if the user would have
2621 hinted that address.
2622 The aspacem state will be correctly updated afterwards.
2623 We however cannot do this last refinement when the user asked
2624 for a fixed mapping, as the user asked a specific address. */
2625 if (sr_isError(sres) && !(arg4 & VKI_MAP_FIXED)) {
2626 advised = 0;
2627 /* try mmap with NULL address and without VKI_MAP_FIXED
2628 to let the kernel decide. */
2629 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2630 arg4,
2631 arg5, arg6);
2632 if (!sr_isError(sres)) {
2633 /* The kernel is supposed to know what it is doing, but let's
2634 do a last sanity check anyway, as if the chosen address had
2635 been initially hinted by the client. The whole point of this
2636 last try was to allow mmap of huge pages to succeed without
2637 making aspacem understand them, on the other hand the kernel
2638 does not know about valgrind reservations, so this mapping
2639 can end up in free space and reservations. */
2640 mreq.start = (Addr)sr_Res(sres);
2641 mreq.len = arg2;
2642 mreq.rkind = MHint;
2643 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2644 vg_assert(mreq_ok && advised == mreq.start);
2648 if (!sr_isError(sres)) {
2649 ULong di_handle;
2650 /* Notify aspacem. */
2651 notify_core_of_mmap(
2652 (Addr)sr_Res(sres), /* addr kernel actually assigned */
2653 arg2, /* length */
2654 arg3, /* prot */
2655 arg4, /* the original flags value */
2656 arg5, /* fd */
2657 arg6 /* offset */
2659 /* Load symbols? */
2660 di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres),
2661 False/*allow_SkFileV*/, (Int)arg5 );
2662 /* Notify the tool. */
2663 notify_tool_of_mmap(
2664 (Addr)sr_Res(sres), /* addr kernel actually assigned */
2665 arg2, /* length */
2666 arg3, /* prot */
2667 di_handle /* so the tool can refer to the read debuginfo later,
2668 if it wants. */
2672 /* Stay sane */
2673 if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED))
2674 vg_assert(sr_Res(sres) == arg1);
2676 return sres;
2680 /* ---------------------------------------------------------------------
2681 The Main Entertainment ... syscall wrappers
2682 ------------------------------------------------------------------ */
2684 /* Note: the PRE() and POST() wrappers are for the actual functions
2685 implementing the system calls in the OS kernel. These mostly have
2686 names like sys_write(); a few have names like old_mmap(). See the
2687 comment for ML_(syscall_table)[] for important info about the __NR_foo
2688 constants and their relationship to the sys_foo() functions.
2690 Some notes about names used for syscalls and args:
2691 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
2692 ambiguity.
2694 - For error messages, we generally use a somewhat generic name
2695 for the syscall (eg. "write" rather than "sys_write"). This should be
2696 good enough for the average user to understand what is happening,
2697 without confusing them with names like "sys_write".
2699 - Also, for error messages the arg names are mostly taken from the man
2700 pages (even though many of those man pages are really for glibc
2701 functions of the same name), rather than from the OS kernel source,
2702 for the same reason -- a user presented with a "bogus foo(bar)" arg
2703 will most likely look at the "foo" man page to see which is the "bar"
2704 arg.
2706 Note that we use our own vki_* types. The one exception is in
2707 PRE_REG_READn calls, where pointer types haven't been changed, because
2708 they don't need to be -- eg. for "foo*" to be used, the type foo need not
2709 be visible.
2711 XXX: some of these are arch-specific, and should be factored out.
2714 #define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
2715 #define POST(name) DEFN_POST_TEMPLATE(generic, name)
2717 PRE(sys_exit)
2719 ThreadState* tst;
2720 /* simple; just make this thread exit */
2721 PRINT("exit( %ld )", SARG1);
2722 PRE_REG_READ1(void, "exit", int, status);
2723 tst = VG_(get_ThreadState)(tid);
2724 /* Set the thread's status to be exiting, then claim that the
2725 syscall succeeded. */
2726 tst->exitreason = VgSrc_ExitThread;
2727 tst->os_state.exitcode = ARG1;
2728 SET_STATUS_Success(0);
2731 PRE(sys_ni_syscall)
2733 PRINT("unimplemented (by the kernel) syscall: %s! (ni_syscall)\n",
2734 VG_SYSNUM_STRING(SYSNO));
2735 PRE_REG_READ0(long, "ni_syscall");
2736 SET_STATUS_Failure( VKI_ENOSYS );
2739 PRE(sys_iopl)
2741 PRINT("sys_iopl ( %" FMT_REGWORD "u )", ARG1);
2742 PRE_REG_READ1(long, "iopl", unsigned long, level);
2745 PRE(sys_fsync)
2747 *flags |= SfMayBlock;
2748 PRINT("sys_fsync ( %" FMT_REGWORD "u )", ARG1);
2749 PRE_REG_READ1(long, "fsync", unsigned int, fd);
2752 PRE(sys_fdatasync)
2754 *flags |= SfMayBlock;
2755 PRINT("sys_fdatasync ( %" FMT_REGWORD "u )", ARG1);
2756 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
2759 PRE(sys_msync)
2761 *flags |= SfMayBlock;
2762 PRINT("sys_msync ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2763 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
2764 PRE_REG_READ3(long, "msync",
2765 unsigned long, start, vki_size_t, length, int, flags);
2766 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
2769 // Nb: getpmsg() and putpmsg() are special additional syscalls used in early
2770 // versions of LiS (Linux Streams). They are not part of the kernel.
2771 // Therefore, we have to provide this type ourself, rather than getting it
2772 // from the kernel sources.
2773 struct vki_pmsg_strbuf {
2774 int maxlen; /* no. of bytes in buffer */
2775 int len; /* no. of bytes returned */
2776 vki_caddr_t buf; /* pointer to data */
2778 PRE(sys_getpmsg)
2780 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
2781 struct vki_pmsg_strbuf *ctrl;
2782 struct vki_pmsg_strbuf *data;
2783 *flags |= SfMayBlock;
2784 PRINT("sys_getpmsg ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
2785 FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,
2786 ARG2, ARG3, ARG4, ARG5);
2787 PRE_REG_READ5(int, "getpmsg",
2788 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2789 int *, bandp, int *, flagsp);
2790 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2791 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2792 if (ctrl && ctrl->maxlen > 0)
2793 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
2794 if (data && data->maxlen > 0)
2795 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
2796 if (ARG4)
2797 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
2798 if (ARG5)
2799 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
2801 POST(sys_getpmsg)
2803 struct vki_pmsg_strbuf *ctrl;
2804 struct vki_pmsg_strbuf *data;
2805 vg_assert(SUCCESS);
2806 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2807 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2808 if (RES == 0 && ctrl && ctrl->len > 0) {
2809 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
2811 if (RES == 0 && data && data->len > 0) {
2812 POST_MEM_WRITE( (Addr)data->buf, data->len);
2816 PRE(sys_putpmsg)
2818 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
2819 struct vki_pmsg_strbuf *ctrl;
2820 struct vki_pmsg_strbuf *data;
2821 *flags |= SfMayBlock;
2822 PRINT("sys_putpmsg ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD
2823 "x, %ld, %ld )", SARG1, ARG2, ARG3, SARG4, SARG5);
2824 PRE_REG_READ5(int, "putpmsg",
2825 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2826 int, band, int, flags);
2827 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2828 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2829 if (ctrl && ctrl->len > 0)
2830 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
2831 if (data && data->len > 0)
2832 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
2835 PRE(sys_getitimer)
2837 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2838 PRINT("sys_getitimer ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2839 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
2841 PRE_timeval_WRITE( "getitimer(&value->it_interval)", &(value->it_interval));
2842 PRE_timeval_WRITE( "getitimer(&value->it_value)", &(value->it_value));
2845 POST(sys_getitimer)
2847 if (ARG2 != (Addr)NULL) {
2848 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2849 POST_timeval_WRITE( &(value->it_interval) );
2850 POST_timeval_WRITE( &(value->it_value) );
2854 PRE(sys_setitimer)
2856 PRINT("sys_setitimer ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2857 SARG1, ARG2, ARG3);
2858 PRE_REG_READ3(long, "setitimer",
2859 int, which,
2860 struct itimerval *, value, struct itimerval *, ovalue);
2861 if (ARG2 != (Addr)NULL) {
2862 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2863 PRE_timeval_READ( "setitimer(&value->it_interval)",
2864 &(value->it_interval));
2865 PRE_timeval_READ( "setitimer(&value->it_value)",
2866 &(value->it_value));
2868 if (ARG3 != (Addr)NULL) {
2869 struct vki_itimerval *ovalue = (struct vki_itimerval*)(Addr)ARG3;
2870 PRE_timeval_WRITE( "setitimer(&ovalue->it_interval)",
2871 &(ovalue->it_interval));
2872 PRE_timeval_WRITE( "setitimer(&ovalue->it_value)",
2873 &(ovalue->it_value));
2877 POST(sys_setitimer)
2879 if (ARG3 != (Addr)NULL) {
2880 struct vki_itimerval *ovalue = (struct vki_itimerval*)(Addr)ARG3;
2881 POST_timeval_WRITE( &(ovalue->it_interval) );
2882 POST_timeval_WRITE( &(ovalue->it_value) );
2886 PRE(sys_chroot)
2888 PRINT("sys_chroot ( %#" FMT_REGWORD "x )", ARG1);
2889 PRE_REG_READ1(long, "chroot", const char *, path);
2890 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
2893 PRE(sys_madvise)
2895 *flags |= SfMayBlock;
2896 PRINT("sys_madvise ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
2897 ARG1, ARG2, SARG3);
2898 PRE_REG_READ3(long, "madvise",
2899 unsigned long, start, vki_size_t, length, int, advice);
2902 #if HAVE_MREMAP
2903 PRE(sys_mremap)
2905 // Nb: this is different to the glibc version described in the man pages,
2906 // which lacks the fifth 'new_address' argument.
2907 if (ARG4 & VKI_MREMAP_FIXED) {
2908 PRINT("sys_mremap ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2909 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2910 ARG1, ARG2, ARG3, ARG4, ARG5);
2911 PRE_REG_READ5(unsigned long, "mremap",
2912 unsigned long, old_addr, unsigned long, old_size,
2913 unsigned long, new_size, unsigned long, flags,
2914 unsigned long, new_addr);
2915 } else {
2916 PRINT("sys_mremap ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
2917 FMT_REGWORD "u, 0x%" FMT_REGWORD "x )",
2918 ARG1, ARG2, ARG3, ARG4);
2919 PRE_REG_READ4(unsigned long, "mremap",
2920 unsigned long, old_addr, unsigned long, old_size,
2921 unsigned long, new_size, unsigned long, flags);
2923 SET_STATUS_from_SysRes(
2924 do_mremap((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
2927 #endif /* HAVE_MREMAP */
2929 PRE(sys_nice)
2931 PRINT("sys_nice ( %ld )", SARG1);
2932 PRE_REG_READ1(long, "nice", int, inc);
2935 PRE(sys_mlock2)
2937 *flags |= SfMayBlock;
2938 PRINT("sys_mlock2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
2939 PRE_REG_READ2(int, "mlock2", void*, addr, vki_size_t, len);
2942 PRE(sys_mlock)
2944 *flags |= SfMayBlock;
2945 PRINT("sys_mlock ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
2946 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
2949 PRE(sys_munlock)
2951 *flags |= SfMayBlock;
2952 PRINT("sys_munlock ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
2953 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
2956 PRE(sys_mlockall)
2958 *flags |= SfMayBlock;
2959 PRINT("sys_mlockall ( %" FMT_REGWORD "x )", ARG1);
2960 PRE_REG_READ1(long, "mlockall", int, flags);
2963 PRE(sys_setpriority)
2965 PRINT("sys_setpriority ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
2966 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
2969 PRE(sys_getpriority)
2971 PRINT("sys_getpriority ( %ld, %ld )", SARG1, SARG2);
2972 PRE_REG_READ2(long, "getpriority", int, which, int, who);
2975 #if !defined(VGO_freebsd)
2976 PRE(sys_pwrite64)
2978 *flags |= SfMayBlock;
2979 #if VG_WORDSIZE == 4
2980 PRINT("sys_pwrite64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
2981 FMT_REGWORD "u, %lld )", ARG1, ARG2, ARG3, (Long)MERGE64(ARG4,ARG5));
2982 PRE_REG_READ5(ssize_t, "pwrite64",
2983 unsigned int, fd, const char *, buf, vki_size_t, count,
2984 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
2985 #elif VG_WORDSIZE == 8
2986 PRINT("sys_pwrite64 ( %lu, %#lx, %lu, %ld )",
2987 ARG1, ARG2, ARG3, SARG4);
2988 PRE_REG_READ4(ssize_t, "pwrite64",
2989 unsigned int, fd, const char *, buf, vki_size_t, count,
2990 Word, offset);
2991 #else
2992 # error Unexpected word size
2993 #endif
2994 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
2996 #endif
2998 PRE(sys_sync)
3000 *flags |= SfMayBlock;
3001 PRINT("sys_sync ( )");
3002 PRE_REG_READ0(long, "sync");
3005 #if !defined(VGP_nanomips_linux)
3006 PRE(sys_fstatfs)
3008 FUSE_COMPATIBLE_MAY_BLOCK();
3009 PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3010 PRE_REG_READ2(long, "fstatfs",
3011 unsigned int, fd, struct statfs *, buf);
3012 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
3015 POST(sys_fstatfs)
3017 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
3020 PRE(sys_fstatfs64)
3022 FUSE_COMPATIBLE_MAY_BLOCK();
3023 PRINT("sys_fstatfs64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3024 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3025 PRE_REG_READ3(long, "fstatfs64",
3026 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
3027 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
3029 POST(sys_fstatfs64)
3031 POST_MEM_WRITE( ARG3, ARG2 );
3033 #endif
3035 PRE(sys_getsid)
3037 PRINT("sys_getsid ( %ld )", SARG1);
3038 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
3041 #if !defined(VGO_freebsd)
3042 PRE(sys_pread64)
3044 *flags |= SfMayBlock;
3045 #if VG_WORDSIZE == 4
3046 PRINT("sys_pread64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3047 FMT_REGWORD "u, %lld )", ARG1, ARG2, ARG3, (Long)MERGE64(ARG4,ARG5));
3048 PRE_REG_READ5(ssize_t, "pread64",
3049 unsigned int, fd, char *, buf, vki_size_t, count,
3050 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
3051 #elif VG_WORDSIZE == 8
3052 PRINT("sys_pread64 ( %lu, %#lx, %lu, %ld )",
3053 ARG1, ARG2, ARG3, SARG4);
3054 PRE_REG_READ4(ssize_t, "pread64",
3055 unsigned int, fd, char *, buf, vki_size_t, count,
3056 Word, offset);
3057 #else
3058 # error Unexpected word size
3059 #endif
3060 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
3062 POST(sys_pread64)
3064 vg_assert(SUCCESS);
3065 if (RES > 0) {
3066 POST_MEM_WRITE( ARG2, RES );
3069 #endif
3071 PRE(sys_mknod)
3073 FUSE_COMPATIBLE_MAY_BLOCK();
3074 PRINT("sys_mknod ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#"
3075 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, ARG2, ARG3 );
3076 PRE_REG_READ3(long, "mknod",
3077 const char *, pathname, int, mode, unsigned, dev);
3078 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
3081 PRE(sys_flock)
3083 *flags |= SfMayBlock;
3084 PRINT("sys_flock ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2 );
3085 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
3088 // Pre_read a char** argument.
3089 void ML_(pre_argv_envp)(Addr a, ThreadId tid, const HChar *s1, const HChar *s2)
3091 while (True) {
3092 Addr a_deref;
3093 Addr* a_p = (Addr*)a;
3094 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
3095 a_deref = *a_p;
3096 if (0 == a_deref)
3097 break;
3098 PRE_MEM_RASCIIZ( s2, a_deref );
3099 a += sizeof(char*);
3103 static Bool i_am_the_only_thread ( void )
3105 Int c = VG_(count_living_threads)();
3106 vg_assert(c >= 1); /* stay sane */
3107 return c == 1;
3110 /* Wait until all other threads disappear. */
3111 void VG_(reap_threads)(ThreadId self)
3113 while (!i_am_the_only_thread()) {
3114 /* Let other thread(s) run */
3115 VG_(vg_yield)();
3116 VG_(poll_signals)(self);
3118 vg_assert(i_am_the_only_thread());
3121 /* This handles the common part of the PRE macro for execve and execveat. */
3122 void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname,
3123 Addr arg_2, Addr arg_3, ExecveType execveType,
3124 Bool check_pathptr)
3126 HChar* path = NULL; /* path to executable */
3127 HChar** envp = NULL;
3128 HChar** argv = NULL;
3129 HChar** arg2copy;
3130 HChar* launcher_basename = NULL;
3131 ThreadState* tst;
3132 Int i, j, tot_args;
3133 SysRes res;
3134 Bool setuid_allowed, trace_this_child;
3135 const char *str;
3136 char str2[30], str3[30];
3137 Addr arg_2_check = arg_2;
3139 switch (execveType) {
3140 case EXECVE:
3141 str = "execve";
3142 break;
3143 case EXECVEAT:
3144 str = "execveat";
3145 break;
3146 case FEXECVE:
3147 str = "fexecve";
3148 break;
3149 default:
3150 vg_assert(False);
3153 VG_(strcpy)(str2, str);
3154 VG_(strcpy)(str3, str);
3156 VG_(strcat)(str2, "(argv)");
3157 VG_(strcat)(str3, "(argv[0])");
3159 /* argv[] should not be NULL and valid. */
3160 PRE_MEM_READ(str2, arg_2_check, sizeof(Addr));
3162 /* argv[0] should not be NULL and valid. */
3163 if (ML_(safe_to_deref)((HChar **) (Addr)arg_2_check, sizeof(HChar *))) {
3164 Addr argv0 = *(Addr*)arg_2_check;
3165 PRE_MEM_RASCIIZ( str3, argv0 );
3166 /* The rest of argv can be NULL or a valid string pointer. */
3167 if (VG_(am_is_valid_for_client)(arg_2_check, sizeof(HChar), VKI_PROT_READ)) {
3168 arg_2_check += sizeof(HChar*);
3169 str3[VG_(strlen)(str)] = '\0';
3170 VG_(strcat)(str3, "(argv[i])");
3171 ML_(pre_argv_envp)( arg_2_check, tid, str2, str3 );
3173 } else {
3174 SET_STATUS_Failure(VKI_EFAULT);
3175 return;
3177 // Reset helper strings to syscall name.
3178 str2[VG_(strlen)(str)] = '\0';
3179 str3[VG_(strlen)(str)] = '\0';
3180 if (arg_3 != 0) {
3181 /* At least the terminating NULL must be addressable. */
3182 if (!ML_(safe_to_deref)((HChar **) (Addr)arg_3, sizeof(HChar *))) {
3183 SET_STATUS_Failure(VKI_EFAULT);
3184 return;
3186 VG_(strcat)(str2, "(envp)");
3187 VG_(strcat)(str3, "(envp[i])");
3188 ML_(pre_argv_envp)( arg_3, tid, str2, str3 );
3191 vg_assert(VG_(is_valid_tid)(tid));
3192 tst = VG_(get_ThreadState)(tid);
3194 /* Erk. If the exec fails, then the following will have made a
3195 mess of things which makes it hard for us to continue. The
3196 right thing to do is piece everything together again in
3197 POST(execve), but that's close to impossible. Instead, we make
3198 an effort to check that the execve will work before actually
3199 doing it. */
3201 /* Check that the name at least begins in client-accessible storage.
3202 If we didn't create it ourselves in execveat. */
3203 if (check_pathptr
3204 && !VG_(am_is_valid_for_client)( pathname, 1, VKI_PROT_READ )) {
3205 SET_STATUS_Failure( VKI_EFAULT );
3206 return;
3209 // debug-only printing
3210 if (0) {
3211 VG_(printf)("pathname = %p(%s)\n", (void*)(Addr)pathname, (HChar*)(Addr)pathname);
3212 if (arg_2) {
3213 VG_(printf)("arg_2 = ");
3214 Int q;
3215 HChar** vec = (HChar**)(Addr)arg_2;
3216 for (q = 0; vec[q]; q++)
3217 VG_(printf)("%p(%s) ", vec[q], vec[q]);
3218 VG_(printf)("\n");
3219 } else {
3220 VG_(printf)("arg_2 = null\n");
3224 // Decide whether or not we want to follow along
3225 { // Make 'child_argv' be a pointer to the child's arg vector
3226 // (skipping the exe name)
3227 const HChar** child_argv = (const HChar**)(Addr)arg_2;
3228 if (child_argv && child_argv[0] == NULL)
3229 child_argv = NULL;
3230 trace_this_child = VG_(should_we_trace_this_child)( (HChar*)(Addr)pathname,
3231 child_argv );
3234 // Do the important checks: it is a file, is executable, permissions are
3235 // ok, etc. We allow setuid executables to run only in the case when
3236 // we are not simulating them, that is, they to be run natively.
3237 setuid_allowed = trace_this_child ? False : True;
3238 res = VG_(pre_exec_check)((const HChar *)(Addr)pathname, NULL, setuid_allowed);
3239 if (sr_isError(res)) {
3240 SET_STATUS_Failure( sr_Err(res) );
3241 return;
3244 /* If we're tracing the child, and the launcher name looks bogus
3245 (possibly because launcher.c couldn't figure it out, see
3246 comments therein) then we have no option but to fail. */
3247 if (trace_this_child
3248 && (VG_(name_of_launcher) == NULL
3249 || VG_(name_of_launcher)[0] != '/')) {
3250 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
3251 return;
3254 /* After this point, we can't recover if the execve fails. */
3255 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)(Addr)pathname);
3258 // Terminate gdbserver if it is active.
3259 if (VG_(clo_vgdb) != Vg_VgdbNo) {
3260 // If the child will not be traced, we need to terminate gdbserver
3261 // to cleanup the gdbserver resources (e.g. the FIFO files).
3262 // If child will be traced, we also terminate gdbserver: the new
3263 // Valgrind will start a fresh gdbserver after exec.
3264 VG_(gdbserver) (0);
3267 /* Resistance is futile. Nuke all other threads. POSIX mandates
3268 this. (Really, nuke them all, since the new process will make
3269 its own new thread.) */
3270 VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
3271 VG_(reap_threads)(tid);
3273 // Set up the child's exe path.
3275 if (trace_this_child) {
3277 // We want to exec the launcher. Get its pre-remembered path.
3278 path = VG_(name_of_launcher);
3279 // VG_(name_of_launcher) should have been acquired by m_main at
3280 // startup.
3281 vg_assert(path);
3283 launcher_basename = VG_(strrchr)(path, '/');
3284 if (launcher_basename == NULL || launcher_basename[1] == 0) {
3285 launcher_basename = path; // hmm, tres dubious
3286 } else {
3287 launcher_basename++;
3290 } else {
3291 path = (HChar*)(Addr)pathname;
3294 // Set up the child's environment.
3296 // Remove the valgrind-specific stuff from the environment so the
3297 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
3298 // This is done unconditionally, since if we are tracing the child,
3299 // the child valgrind will set up the appropriate client environment.
3300 // Nb: we make a copy of the environment before trying to mangle it
3301 // as it might be in read-only memory (this was bug #101881).
3303 // Then, if tracing the child, set VALGRIND_LIB for it.
3305 if (arg_3 == 0) {
3306 envp = NULL;
3307 } else {
3308 envp = VG_(env_clone)( (HChar**)(Addr)arg_3 );
3309 if (envp == NULL) goto hosed;
3310 VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL );
3313 if (trace_this_child) {
3314 // Set VALGRIND_LIB in arg_3 (the environment)
3315 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
3318 // Set up the child's args. If not tracing it, they are
3319 // simply arg_2. Otherwise, they are
3321 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [pathname] ++ arg_2[1..]
3323 // except that the first VG_(args_for_valgrind_noexecpass) args
3324 // are omitted.
3326 if (!trace_this_child) {
3327 argv = (HChar**)(Addr)arg_2;
3328 } else {
3329 vg_assert( VG_(args_for_valgrind) );
3330 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
3331 vg_assert( VG_(args_for_valgrind_noexecpass)
3332 <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
3333 /* how many args in total will there be? */
3334 // launcher basename
3335 tot_args = 1;
3336 // V's args
3337 tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
3338 tot_args -= VG_(args_for_valgrind_noexecpass);
3339 // name of client exe
3340 tot_args++;
3341 // args for client exe, skipping [0]
3342 arg2copy = (HChar**)(Addr)arg_2;
3343 if (arg2copy && arg2copy[0]) {
3344 for (i = 1; arg2copy[i]; i++)
3345 tot_args++;
3347 // allocate
3348 argv = VG_(malloc)( "di.syswrap.pre_sys_execve.1",
3349 (tot_args+1) * sizeof(HChar*) );
3350 // copy
3351 j = 0;
3352 argv[j++] = launcher_basename;
3353 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
3354 if (i < VG_(args_for_valgrind_noexecpass))
3355 continue;
3356 argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
3358 argv[j++] = (HChar*)(Addr)pathname;
3359 if (arg2copy && arg2copy[0])
3360 for (i = 1; arg2copy[i]; i++)
3361 argv[j++] = arg2copy[i];
3362 argv[j++] = NULL;
3363 // check
3364 vg_assert(j == tot_args+1);
3368 Set the signal state up for exec.
3370 We need to set the real signal state to make sure the exec'd
3371 process gets SIG_IGN properly.
3373 Also set our real sigmask to match the client's sigmask so that
3374 the exec'd child will get the right mask. First we need to
3375 clear out any pending signals so they they don't get delivered,
3376 which would confuse things.
3378 XXX This is a bug - the signals should remain pending, and be
3379 delivered to the new process after exec. There's also a
3380 race-condition, since if someone delivers us a signal between
3381 the sigprocmask and the execve, we'll still get the signal. Oh
3382 well.
3385 vki_sigset_t allsigs;
3386 vki_siginfo_t info;
3388 /* What this loop does: it queries SCSS (the signal state that
3389 the client _thinks_ the kernel is in) by calling
3390 VG_(do_sys_sigaction), and modifies the real kernel signal
3391 state accordingly. */
3392 for (i = 1; i < VG_(max_signal); i++) {
3393 vki_sigaction_fromK_t sa_f;
3394 vki_sigaction_toK_t sa_t;
3395 VG_(do_sys_sigaction)(i, NULL, &sa_f);
3396 VG_(convert_sigaction_fromK_to_toK)(&sa_f, &sa_t);
3397 if (sa_t.ksa_handler == VKI_SIG_IGN)
3398 VG_(sigaction)(i, &sa_t, NULL);
3399 else {
3400 sa_t.ksa_handler = VKI_SIG_DFL;
3401 VG_(sigaction)(i, &sa_t, NULL);
3405 VG_(sigfillset)(&allsigs);
3406 while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
3409 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
3412 if (0) {
3413 HChar **cpp;
3414 VG_(printf)("exec: %s\n", path);
3415 for (cpp = argv; cpp && *cpp; cpp++)
3416 VG_(printf)("argv: %s\n", *cpp);
3417 if (0)
3418 for (cpp = envp; cpp && *cpp; cpp++)
3419 VG_(printf)("env: %s\n", *cpp);
3422 // always execute this because it's executing valgrind, not the "target" exe
3423 SET_STATUS_from_SysRes(
3424 VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp));
3426 /* If we got here, then the execve failed. We've already made way
3427 too much of a mess to continue, so we have to abort. */
3428 hosed:
3429 vg_assert(FAILURE);
3430 VG_(message)(Vg_UserMsg, "execve(%#" FMT_REGWORD "x(%s), %#" FMT_REGWORD
3431 "x, %#" FMT_REGWORD "x) failed, errno %lu\n",
3432 pathname, (HChar*)(Addr)pathname, arg_2, arg_3, ERR);
3433 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
3434 "execve() failing, so I'm dying.\n");
3435 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
3436 "or work out how to recover.\n");
3437 VG_(exit)(101);
3441 // XXX: prototype here seemingly doesn't match the prototype for i386-linux,
3442 // but it seems to work nonetheless...
3443 PRE(sys_execve)
3445 PRINT("sys_execve ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#"
3446 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, ARG2, ARG3);
3447 PRE_REG_READ3(vki_off_t, "execve",
3448 char *, filename, char **, argv, char **, envp);
3449 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
3451 char *pathname = (char *)ARG1;
3452 Addr arg_2 = (Addr)ARG2;
3453 Addr arg_3 = (Addr)ARG3;
3455 handle_pre_sys_execve(tid, status, (Addr)pathname, arg_2, arg_3, EXECVE, True);
3458 PRE(sys_access)
3460 PRINT("sys_access ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
3461 (HChar*)(Addr)ARG1, SARG2);
3462 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
3463 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
3466 PRE(sys_alarm)
3468 PRINT("sys_alarm ( %" FMT_REGWORD "u )", ARG1);
3469 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
3472 PRE(sys_brk)
3474 Addr brk_limit = VG_(brk_limit);
3475 Addr brk_new;
3477 /* libc says: int brk(void *end_data_segment);
3478 kernel says: void* brk(void* end_data_segment); (more or less)
3480 libc returns 0 on success, and -1 (and sets errno) on failure.
3481 Nb: if you ask to shrink the dataseg end below what it
3482 currently is, that always succeeds, even if the dataseg end
3483 doesn't actually change (eg. brk(0)). Unless it seg faults.
3485 Kernel returns the new dataseg end. If the brk() failed, this
3486 will be unchanged from the old one. That's why calling (kernel)
3487 brk(0) gives the current dataseg end (libc brk() just returns
3488 zero in that case).
3490 Both will seg fault if you shrink it back into a text segment.
3492 PRINT("sys_brk ( %#" FMT_REGWORD "x )", ARG1);
3493 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
3495 brk_new = do_brk(ARG1, tid);
3496 SET_STATUS_Success( brk_new );
3498 if (brk_new == ARG1) {
3499 /* brk() succeeded */
3500 if (brk_new < brk_limit) {
3501 /* successfully shrunk the data segment. */
3502 VG_TRACK( die_mem_brk, (Addr)ARG1,
3503 brk_limit-ARG1 );
3504 } else
3505 if (brk_new > brk_limit) {
3506 /* successfully grew the data segment */
3507 VG_TRACK( new_mem_brk, brk_limit,
3508 ARG1-brk_limit, tid );
3510 } else {
3511 /* brk() failed */
3512 vg_assert(brk_limit == brk_new);
3516 PRE(sys_chdir)
3518 FUSE_COMPATIBLE_MAY_BLOCK();
3519 PRINT("sys_chdir ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
3520 PRE_REG_READ1(long, "chdir", const char *, path);
3521 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
3524 PRE(sys_chmod)
3526 FUSE_COMPATIBLE_MAY_BLOCK();
3527 PRINT("sys_chmod ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,
3528 (HChar*)(Addr)ARG1, ARG2);
3529 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
3530 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
3533 PRE(sys_chown)
3535 FUSE_COMPATIBLE_MAY_BLOCK();
3536 PRINT("sys_chown ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
3537 FMT_REGWORD "x )", ARG1,(char*)(Addr)ARG1,ARG2,ARG3);
3538 PRE_REG_READ3(long, "chown",
3539 const char *, path, vki_uid_t, owner, vki_gid_t, group);
3540 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
3543 PRE(sys_lchown)
3545 FUSE_COMPATIBLE_MAY_BLOCK();
3546 PRINT("sys_lchown ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
3547 FMT_REGWORD "x )", ARG1,(char*)(Addr)ARG1,ARG2,ARG3);
3548 PRE_REG_READ3(long, "lchown",
3549 const char *, path, vki_uid_t, owner, vki_gid_t, group);
3550 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
3553 PRE(sys_close)
3555 FUSE_COMPATIBLE_MAY_BLOCK();
3556 PRINT("sys_close ( %" FMT_REGWORD "u )", ARG1);
3557 PRE_REG_READ1(long, "close", unsigned int, fd);
3559 /* Detect and negate attempts by the client to close Valgrind's log fd */
3560 if ( (!ML_(fd_allowed)(ARG1, "close", tid, False))
3561 /* If doing -d style logging (which is to fd=2), don't
3562 allow that to be closed either. */
3563 || (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0) )
3564 SET_STATUS_Failure( VKI_EBADF );
3565 else {
3566 /* We used to do close tracking in the POST handler, but that is
3567 only called on success. Even if the close syscall fails the
3568 file descriptor is still really closed/invalid. So we do the
3569 recording and checking here. */
3570 if (VG_(clo_track_fds)) ML_(record_fd_close)(tid, ARG1);
3574 PRE(sys_dup)
3576 PRINT("sys_dup ( %" FMT_REGWORD "u )", ARG1);
3577 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
3580 POST(sys_dup)
3582 vg_assert(SUCCESS);
3583 if (!ML_(fd_allowed)(RES, "dup", tid, True)) {
3584 VG_(close)(RES);
3585 SET_STATUS_Failure( VKI_EMFILE );
3586 } else {
3587 if (VG_(clo_track_fds))
3588 ML_(record_fd_open_named)(tid, RES);
3592 PRE(sys_dup2)
3594 PRINT("sys_dup2 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3595 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
3596 if (!ML_(fd_allowed)(ARG2, "dup2", tid, True))
3597 SET_STATUS_Failure( VKI_EBADF );
3600 POST(sys_dup2)
3602 vg_assert(SUCCESS);
3603 if (VG_(clo_track_fds))
3604 ML_(record_fd_open_named)(tid, RES);
3607 PRE(sys_fchdir)
3609 FUSE_COMPATIBLE_MAY_BLOCK();
3610 PRINT("sys_fchdir ( %" FMT_REGWORD "u )", ARG1);
3611 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
3614 PRE(sys_fchown)
3616 FUSE_COMPATIBLE_MAY_BLOCK();
3617 PRINT("sys_fchown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3618 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3619 PRE_REG_READ3(long, "fchown",
3620 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
3623 PRE(sys_fchmod)
3625 FUSE_COMPATIBLE_MAY_BLOCK();
3626 PRINT("sys_fchmod ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3627 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
3630 #if !defined(VGP_nanomips_linux) && !defined (VGO_freebsd)
3631 PRE(sys_newfstat)
3633 FUSE_COMPATIBLE_MAY_BLOCK();
3634 PRINT("sys_newfstat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3635 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
3636 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
3639 POST(sys_newfstat)
3641 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
3643 #endif
3645 #if !defined(VGO_solaris) && !defined(VGP_arm64_linux) && \
3646 !defined(VGP_nanomips_linux)
3647 static vki_sigset_t fork_saved_mask;
3649 // In Linux, the sys_fork() function varies across architectures, but we
3650 // ignore the various args it gets, and so it looks arch-neutral. Hmm.
3651 PRE(sys_fork)
3653 Bool is_child;
3654 Int child_pid;
3655 vki_sigset_t mask;
3657 PRINT("sys_fork ( )");
3658 PRE_REG_READ0(long, "fork");
3660 /* Block all signals during fork, so that we can fix things up in
3661 the child without being interrupted. */
3662 VG_(sigfillset)(&mask);
3663 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
3665 VG_(do_atfork_pre)(tid);
3667 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
3669 if (!SUCCESS) return;
3671 #if defined(VGO_linux) || defined(VGO_freebsd)
3672 // RES is 0 for child, non-0 (the child's PID) for parent.
3673 is_child = ( RES == 0 ? True : False );
3674 child_pid = ( is_child ? -1 : RES );
3675 #elif defined(VGO_darwin)
3676 // RES is the child's pid. RESHI is 1 for child, 0 for parent.
3677 is_child = RESHI;
3678 child_pid = RES;
3679 #else
3680 # error Unknown OS
3681 #endif
3683 if (is_child) {
3684 VG_(do_atfork_child)(tid);
3686 /* restore signal mask */
3687 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
3688 } else {
3689 VG_(do_atfork_parent)(tid);
3691 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), child_pid);
3693 /* restore signal mask */
3694 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
3697 #endif // !defined(VGO_solaris) && !defined(VGP_arm64_linux)
3699 PRE(sys_ftruncate)
3701 *flags |= SfMayBlock;
3702 PRINT("sys_ftruncate ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3703 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
3706 PRE(sys_truncate)
3708 *flags |= SfMayBlock;
3709 PRINT("sys_truncate ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
3710 ARG1, (HChar*)(Addr)ARG1, ARG2);
3711 PRE_REG_READ2(long, "truncate",
3712 const char *, path, unsigned long, length);
3713 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
3716 PRE(sys_ftruncate64)
3718 *flags |= SfMayBlock;
3719 #if VG_WORDSIZE == 4
3720 PRINT("sys_ftruncate64 ( %" FMT_REGWORD "u, %llu )", ARG1,
3721 MERGE64(ARG2,ARG3));
3722 PRE_REG_READ3(long, "ftruncate64",
3723 unsigned int, fd,
3724 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
3725 #else
3726 PRINT("sys_ftruncate64 ( %lu, %lu )", ARG1, ARG2);
3727 PRE_REG_READ2(long, "ftruncate64",
3728 unsigned int,fd, UWord,length);
3729 #endif
3732 PRE(sys_truncate64)
3734 *flags |= SfMayBlock;
3735 #if VG_WORDSIZE == 4
3736 PRINT("sys_truncate64 ( %#" FMT_REGWORD "x, %lld )", ARG1,
3737 (Long)MERGE64(ARG2, ARG3));
3738 PRE_REG_READ3(long, "truncate64",
3739 const char *, path,
3740 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
3741 #else
3742 PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)ARG2);
3743 PRE_REG_READ2(long, "truncate64",
3744 const char *,path, UWord,length);
3745 #endif
3746 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
3749 PRE(sys_getdents)
3751 *flags |= SfMayBlock;
3752 PRINT("sys_getdents ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
3753 "u )", ARG1, ARG2, ARG3);
3754 PRE_REG_READ3(long, "getdents",
3755 unsigned int, fd, struct vki_dirent *, dirp,
3756 unsigned int, count);
3757 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
3760 POST(sys_getdents)
3762 vg_assert(SUCCESS);
3763 if (RES > 0)
3764 POST_MEM_WRITE( ARG2, RES );
3767 PRE(sys_getdents64)
3769 *flags |= SfMayBlock;
3770 PRINT("sys_getdents64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3771 FMT_REGWORD "u )",ARG1, ARG2, ARG3);
3772 PRE_REG_READ3(long, "getdents64",
3773 unsigned int, fd, struct vki_dirent64 *, dirp,
3774 unsigned int, count);
3775 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
3778 POST(sys_getdents64)
3780 vg_assert(SUCCESS);
3781 if (RES > 0)
3782 POST_MEM_WRITE( ARG2, RES );
3785 PRE(sys_getgroups)
3787 PRINT("sys_getgroups ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3788 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
3789 if (ARG1 > 0)
3790 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
3793 POST(sys_getgroups)
3795 vg_assert(SUCCESS);
3796 if (ARG1 > 0 && RES > 0)
3797 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
3800 PRE(sys_getcwd)
3802 // Comment from linux/fs/dcache.c:
3803 // NOTE! The user-level library version returns a character pointer.
3804 // The kernel system call just returns the length of the buffer filled
3805 // (which includes the ending '\0' character), or a negative error
3806 // value.
3807 // Is this Linux-specific? If so it should be moved to syswrap-linux.c.
3808 PRINT("sys_getcwd ( %#" FMT_REGWORD "x, %llu )", ARG1,(ULong)ARG2);
3809 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
3810 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
3813 POST(sys_getcwd)
3815 vg_assert(SUCCESS);
3816 if (RES != (Addr)NULL)
3817 POST_MEM_WRITE( ARG1, RES );
3820 PRE(sys_geteuid)
3822 PRINT("sys_geteuid ( )");
3823 PRE_REG_READ0(long, "geteuid");
3826 PRE(sys_getegid)
3828 PRINT("sys_getegid ( )");
3829 PRE_REG_READ0(long, "getegid");
3832 PRE(sys_getgid)
3834 PRINT("sys_getgid ( )");
3835 PRE_REG_READ0(long, "getgid");
3838 PRE(sys_getpid)
3840 PRINT("sys_getpid ()");
3841 PRE_REG_READ0(long, "getpid");
3844 PRE(sys_getpgid)
3846 PRINT("sys_getpgid ( %ld )", SARG1);
3847 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
3850 PRE(sys_getpgrp)
3852 PRINT("sys_getpgrp ()");
3853 PRE_REG_READ0(long, "getpgrp");
3856 PRE(sys_getppid)
3858 PRINT("sys_getppid ()");
3859 PRE_REG_READ0(long, "getppid");
3862 static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
3864 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
3866 #ifdef _RLIMIT_POSIX_FLAG
3867 // Darwin will sometimes set _RLIMIT_POSIX_FLAG on getrlimit calls.
3868 // Unset it here to make the switch case below work correctly.
3869 a1 &= ~_RLIMIT_POSIX_FLAG;
3870 #endif
3872 switch (a1) {
3873 case VKI_RLIMIT_NOFILE:
3874 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
3875 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
3876 break;
3878 case VKI_RLIMIT_DATA:
3879 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
3880 break;
3882 case VKI_RLIMIT_STACK:
3883 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
3884 break;
3888 PRE(sys_old_getrlimit)
3890 PRINT("sys_old_getrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3891 ARG1, ARG2);
3892 PRE_REG_READ2(long, "old_getrlimit",
3893 unsigned int, resource, struct rlimit *, rlim);
3894 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
3897 POST(sys_old_getrlimit)
3899 common_post_getrlimit(tid, ARG1, ARG2);
3902 PRE(sys_getrlimit)
3904 PRINT("sys_getrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3905 PRE_REG_READ2(long, "getrlimit",
3906 unsigned int, resource, struct rlimit *, rlim);
3907 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
3910 POST(sys_getrlimit)
3912 common_post_getrlimit(tid, ARG1, ARG2);
3915 PRE(sys_getrusage)
3917 PRINT("sys_getrusage ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3918 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
3919 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
3922 POST(sys_getrusage)
3924 vg_assert(SUCCESS);
3925 if (RES == 0)
3926 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
3929 PRE(sys_gettimeofday)
3931 PRINT("sys_gettimeofday ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3932 ARG1,ARG2);
3933 PRE_REG_READ2(long, "gettimeofday",
3934 struct timeval *, tv, struct timezone *, tz);
3935 // GrP fixme does darwin write to *tz anymore?
3936 if (ARG1 != 0)
3937 PRE_timeval_WRITE( "gettimeofday(tv)", (Addr)ARG1 );
3938 if (ARG2 != 0)
3939 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3942 POST(sys_gettimeofday)
3944 vg_assert(SUCCESS);
3945 if (RES == 0) {
3946 if (ARG1 != 0)
3947 POST_timeval_WRITE( (Addr)ARG1 );
3948 if (ARG2 != 0)
3949 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
3953 PRE(sys_settimeofday)
3955 PRINT("sys_settimeofday ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3956 ARG1,ARG2);
3957 PRE_REG_READ2(long, "settimeofday",
3958 struct timeval *, tv, struct timezone *, tz);
3959 if (ARG1 != 0)
3960 PRE_timeval_READ( "settimeofday(tv)", (Addr)ARG1 );
3961 if (ARG2 != 0) {
3962 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
3963 /* maybe should warn if tz->tz_dsttime is non-zero? */
3967 PRE(sys_getuid)
3969 PRINT("sys_getuid ( )");
3970 PRE_REG_READ0(long, "getuid");
3973 void ML_(PRE_unknown_ioctl)(ThreadId tid, UWord request, UWord arg)
3975 /* We don't have any specific information on it, so
3976 try to do something reasonable based on direction and
3977 size bits. The encoding scheme is described in
3978 /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h .
3980 According to Simon Hausmann, _IOC_READ means the kernel
3981 writes a value to the ioctl value passed from the user
3982 space and the other way around with _IOC_WRITE. */
3984 #if defined(VGO_solaris)
3985 /* Majority of Solaris ioctl requests does not honour direction hints. */
3986 UInt dir = _VKI_IOC_NONE;
3987 #else
3988 UInt dir = _VKI_IOC_DIR(request);
3989 #endif
3990 UInt size = _VKI_IOC_SIZE(request);
3992 if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) {
3994 * Be very lax about ioctl handling; the only
3995 * assumption is that the size is correct. Doesn't
3996 * require the full buffer to be initialized when
3997 * writing. Without this, using some device
3998 * drivers with a large number of strange ioctl
3999 * commands becomes very tiresome.
4001 } else if (dir == _VKI_IOC_NONE && size > 0) {
4002 static UWord unknown_ioctl[10];
4003 static Int moans = sizeof(unknown_ioctl) / sizeof(unknown_ioctl[0]);
4005 if (moans > 0 && !VG_(clo_xml)) {
4006 /* Check if have not already moaned for this request. */
4007 UInt i;
4008 for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) {
4009 if (unknown_ioctl[i] == request)
4010 break;
4011 if (unknown_ioctl[i] == 0) {
4012 unknown_ioctl[i] = request;
4013 moans--;
4014 VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx"
4015 " with no direction hints.\n", request);
4016 VG_(umsg)(" This could cause spurious value errors to appear.\n");
4017 VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for "
4018 "guidance on writing a proper wrapper.\n" );
4019 //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
4020 return;
4024 } else {
4025 //VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request);
4026 //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
4027 if ((dir & _VKI_IOC_WRITE) && size > 0)
4028 PRE_MEM_READ( "ioctl(generic)", arg, size);
4029 if ((dir & _VKI_IOC_READ) && size > 0)
4030 PRE_MEM_WRITE( "ioctl(generic)", arg, size);
4034 void ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg)
4036 /* We don't have any specific information on it, so
4037 try to do something reasonable based on direction and
4038 size bits. The encoding scheme is described in
4039 /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h .
4041 According to Simon Hausmann, _IOC_READ means the kernel
4042 writes a value to the ioctl value passed from the user
4043 space and the other way around with _IOC_WRITE. */
4045 UInt dir = _VKI_IOC_DIR(request);
4046 UInt size = _VKI_IOC_SIZE(request);
4047 if (size > 0 && (dir & _VKI_IOC_READ)
4048 && res == 0
4049 && arg != (Addr)NULL) {
4050 POST_MEM_WRITE(arg, size);
4055 If we're sending a SIGKILL to one of our own threads, then simulate
4056 it rather than really sending the signal, so that the target thread
4057 gets a chance to clean up. Returns True if we did the killing (or
4058 no killing is necessary), and False if the caller should use the
4059 normal kill syscall.
4061 "pid" is any pid argument which can be passed to kill; group kills
4062 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4063 they'll most likely hit all the threads and we won't need to worry
4064 about cleanup. In truth, we can't fully emulate these multicast
4065 kills.
4067 "tgid" is a thread group id. If it is not -1, then the target
4068 thread must be in that thread group.
4070 Bool ML_(do_sigkill)(Int pid, Int tgid)
4072 ThreadState *tst;
4073 ThreadId tid;
4075 if (pid <= 0)
4076 return False;
4078 tid = VG_(lwpid_to_vgtid)(pid);
4079 if (tid == VG_INVALID_THREADID)
4080 return False; /* none of our threads */
4082 tst = VG_(get_ThreadState)(tid);
4083 if (tst == NULL || tst->status == VgTs_Empty)
4084 return False; /* hm, shouldn't happen */
4086 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4087 return False; /* not the right thread group */
4089 /* Fatal SIGKILL sent to one of our threads.
4090 "Handle" the signal ourselves, as trying to have tid
4091 handling the signal causes termination problems (see #409367
4092 and #409141).
4093 Moreover, as a process cannot do anything when receiving SIGKILL,
4094 it is not particularly crucial that "tid" does the work to
4095 terminate the process. */
4097 if (VG_(clo_trace_signals))
4098 VG_(message)(Vg_DebugMsg,
4099 "Thread %u %s being killed with SIGKILL, running tid: %u\n",
4100 tst->tid, VG_(name_of_ThreadStatus) (tst->status), VG_(running_tid));
4102 if (!VG_(is_running_thread)(tid))
4103 tst = VG_(get_ThreadState)(VG_(running_tid));
4104 VG_(nuke_all_threads_except) (VG_(running_tid), VgSrc_FatalSig);
4105 VG_(reap_threads)(VG_(running_tid));
4106 tst->exitreason = VgSrc_FatalSig;
4107 tst->os_state.fatalsig = VKI_SIGKILL;
4109 return True;
4112 PRE(sys_kill)
4114 PRINT("sys_kill ( %ld, %ld )", SARG1, SARG2);
4115 PRE_REG_READ2(long, "kill", int, pid, int, signal);
4116 if (!ML_(client_signal_OK)(ARG2)) {
4117 SET_STATUS_Failure( VKI_EINVAL );
4118 return;
4121 /* If we're sending SIGKILL, check to see if the target is one of
4122 our threads and handle it specially. */
4123 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
4124 SET_STATUS_Success(0);
4125 else
4126 /* re syscall3: Darwin has a 3rd arg, which is a flag (boolean)
4127 affecting how posix-compliant the call is. I guess it is
4128 harmless to pass the 3rd arg on other platforms; hence pass
4129 it on all. */
4130 SET_STATUS_from_SysRes( VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3) );
4132 if (VG_(clo_trace_signals))
4133 VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld\n",
4134 SARG2, SARG1);
4136 /* This kill might have given us a pending signal. Ask for a check once
4137 the syscall is done. */
4138 *flags |= SfPollAfter;
4141 PRE(sys_link)
4143 *flags |= SfMayBlock;
4144 PRINT("sys_link ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )", ARG1,
4145 (char*)(Addr)ARG1,ARG2,(char*)(Addr)ARG2);
4146 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
4147 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4148 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
4151 #if !defined(VGP_nanomips_linux) && !defined(VGO_freebsd)
4152 PRE(sys_newlstat)
4154 PRINT("sys_newlstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,
4155 (char*)(Addr)ARG1,ARG2);
4156 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
4157 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4158 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
4161 POST(sys_newlstat)
4163 vg_assert(SUCCESS);
4164 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4166 #endif
4168 PRE(sys_mkdir)
4170 *flags |= SfMayBlock;
4171 PRINT("sys_mkdir ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
4172 (HChar*)(Addr)ARG1, SARG2);
4173 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
4174 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
4177 PRE(sys_mprotect)
4179 PRINT("sys_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4180 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4181 PRE_REG_READ3(long, "mprotect",
4182 unsigned long, addr, vki_size_t, len, unsigned long, prot);
4184 Addr addr = ARG1;
4185 SizeT len = ARG2;
4186 Int prot = ARG3;
4188 handle_sys_mprotect (tid, status, &addr, &len, &prot);
4190 ARG1 = addr;
4191 ARG2 = len;
4192 ARG3 = prot;
4194 /* This will be called from the generic mprotect, or the linux specific
4195 pkey_mprotect. Pass pointers to ARG1, ARG2 and ARG3 as addr, len and prot,
4196 they might be adjusted and have to assigned back to ARG1, ARG2 and ARG3. */
4197 void handle_sys_mprotect(ThreadId tid, SyscallStatus* status,
4198 Addr *addr, SizeT *len, Int *prot)
4200 if (!ML_(valid_client_addr)(*addr, *len, tid, "mprotect")) {
4201 #if defined(VGO_freebsd)
4202 SET_STATUS_Failure( VKI_EINVAL );
4203 #else
4204 SET_STATUS_Failure( VKI_ENOMEM );
4205 #endif
4207 #if defined(VKI_PROT_GROWSDOWN)
4208 else
4209 if (*prot & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
4210 /* Deal with mprotects on growable stack areas.
4212 The critical files to understand all this are mm/mprotect.c
4213 in the kernel and sysdeps/unix/sysv/linux/dl-execstack.c in
4214 glibc.
4216 The kernel provides PROT_GROWSDOWN and PROT_GROWSUP which
4217 round the start/end address of mprotect to the start/end of
4218 the underlying vma and glibc uses that as an easy way to
4219 change the protection of the stack by calling mprotect on the
4220 last page of the stack with PROT_GROWSDOWN set.
4222 The sanity check provided by the kernel is that the vma must
4223 have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate. */
4224 UInt grows = *prot & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
4225 NSegment const *aseg = VG_(am_find_nsegment)(*addr);
4226 NSegment const *rseg;
4228 vg_assert(aseg);
4230 if (grows == VKI_PROT_GROWSDOWN) {
4231 rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ );
4232 if (rseg
4233 && rseg->kind == SkResvn
4234 && rseg->smode == SmUpper
4235 && rseg->end+1 == aseg->start) {
4236 Addr end = *addr + *len;
4237 *addr = aseg->start;
4238 *len = end - aseg->start;
4239 *prot &= ~VKI_PROT_GROWSDOWN;
4240 } else {
4241 SET_STATUS_Failure( VKI_EINVAL );
4243 } else if (grows == VKI_PROT_GROWSUP) {
4244 rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
4245 if (rseg
4246 && rseg->kind == SkResvn
4247 && rseg->smode == SmLower
4248 && aseg->end+1 == rseg->start) {
4249 *len = aseg->end - *addr + 1;
4250 *prot &= ~VKI_PROT_GROWSUP;
4251 } else {
4252 SET_STATUS_Failure( VKI_EINVAL );
4254 } else {
4255 /* both GROWSUP and GROWSDOWN */
4256 SET_STATUS_Failure( VKI_EINVAL );
4259 #endif // defined(VKI_PROT_GROWSDOWN)
4262 POST(sys_mprotect)
4264 Addr a = ARG1;
4265 SizeT len = ARG2;
4266 Int prot = ARG3;
4268 ML_(notify_core_and_tool_of_mprotect)(a, len, prot);
4271 PRE(sys_munmap)
4273 if (0) VG_(printf)(" munmap( %#" FMT_REGWORD "x )\n", ARG1);
4274 PRINT("sys_munmap ( %#" FMT_REGWORD "x, %llu )", ARG1,(ULong)ARG2);
4275 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
4277 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
4278 SET_STATUS_Failure( VKI_EINVAL );
4281 POST(sys_munmap)
4283 Addr a = ARG1;
4284 SizeT len = ARG2;
4286 ML_(notify_core_and_tool_of_munmap)( a, len );
4289 PRE(sys_mincore)
4291 PRINT("sys_mincore ( %#" FMT_REGWORD "x, %llu, %#" FMT_REGWORD "x )",
4292 ARG1, (ULong)ARG2, ARG3);
4293 PRE_REG_READ3(long, "mincore",
4294 unsigned long, start, vki_size_t, length,
4295 unsigned char *, vec);
4296 PRE_MEM_WRITE( "mincore(vec)", ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
4298 POST(sys_mincore)
4300 POST_MEM_WRITE( ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
4303 PRE(sys_nanosleep)
4305 *flags |= SfMayBlock|SfPostOnFail;
4306 PRINT("sys_nanosleep ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4307 PRE_REG_READ2(long, "nanosleep",
4308 struct timespec *, req, struct timespec *, rem);
4309 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4310 if (ARG2 != 0)
4311 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
4314 POST(sys_nanosleep)
4316 vg_assert(SUCCESS || FAILURE);
4317 if (ARG2 != 0 && FAILURE && ERR == VKI_EINTR)
4318 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
4321 #if defined(VGO_linux) || defined(VGO_solaris)
4322 /* Handles the case where the open is of /proc/self/auxv or
4323 /proc/<pid>/auxv, and just gives out a copy of the fd for the
4324 fake file we cooked up at startup (in m_main). Also, seeks the
4325 cloned fd back to the start.
4326 Returns True if auxv open was handled (status is set). */
4327 Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename,
4328 int flags)
4330 HChar name[30]; // large enough
4332 if (!ML_(safe_to_deref)((const void *) filename, 1))
4333 return False;
4335 /* Opening /proc/<pid>/auxv or /proc/self/auxv? */
4336 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
4337 if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/auxv"))
4338 return False;
4340 /* Allow to open the file only for reading. */
4341 if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
4342 SET_STATUS_Failure(VKI_EACCES);
4343 return True;
4346 # if defined(VGO_solaris)
4347 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_auxv_fd));
4348 SysRes sres = VG_(open)(name, flags, 0);
4349 SET_STATUS_from_SysRes(sres);
4350 # else
4351 SysRes sres = VG_(dup)(VG_(cl_auxv_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);
4358 # endif
4360 return True;
4362 #endif // defined(VGO_linux) || defined(VGO_solaris)
4364 #if defined(VGO_linux)
4365 Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename,
4366 int flags)
4368 HChar name[30]; // large enough for /proc/<int>/exe
4370 if (!ML_(safe_to_deref)((const void *) filename, 1))
4371 return False;
4373 /* Opening /proc/<pid>/exe or /proc/self/exe? */
4374 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
4375 if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe"))
4376 return False;
4378 /* Allow to open the file only for reading. */
4379 if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
4380 SET_STATUS_Failure(VKI_EACCES);
4381 return True;
4384 SysRes sres = VG_(dup)(VG_(cl_exec_fd));
4385 SET_STATUS_from_SysRes(sres);
4386 if (!sr_isError(sres)) {
4387 OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
4388 if (off < 0)
4389 SET_STATUS_Failure(VKI_EMFILE);
4392 return True;
4394 #endif // defined(VGO_linux)
4396 PRE(sys_open)
4398 if (ARG2 & VKI_O_CREAT) {
4399 // 3-arg version
4400 PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld, %ld )",ARG1,
4401 (HChar*)(Addr)ARG1, SARG2, SARG3);
4402 PRE_REG_READ3(long, "open",
4403 const char *, filename, int, flags, int, mode);
4404 } else {
4405 // 2-arg version
4406 PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld )",ARG1,
4407 (HChar*)(Addr)ARG1, SARG2);
4408 PRE_REG_READ2(long, "open",
4409 const char *, filename, int, flags);
4411 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
4413 #if defined(VGO_linux)
4414 /* Handle the case where the open is of /proc/self/cmdline or
4415 /proc/<pid>/cmdline, and just give it a copy of the fd for the
4416 fake file we cooked up at startup (in m_main). Also, seek the
4417 cloned fd back to the start. */
4419 HChar name[30]; // large enough
4420 HChar* arg1s = (HChar*) (Addr)ARG1;
4421 SysRes sres;
4423 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
4424 if (ML_(safe_to_deref)( arg1s, 1 )
4425 && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/cmdline"))) {
4426 sres = VG_(dup)( VG_(cl_cmdline_fd) );
4427 SET_STATUS_from_SysRes( sres );
4428 if (!sr_isError(sres)) {
4429 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
4430 if (off < 0)
4431 SET_STATUS_Failure( VKI_EMFILE );
4433 return;
4437 /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv
4438 or /proc/self/exe or /proc/<pid>/exe. */
4439 if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2)
4440 || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2))
4441 return;
4442 #endif // defined(VGO_linux)
4444 /* Otherwise handle normally */
4445 *flags |= SfMayBlock;
4448 POST(sys_open)
4450 vg_assert(SUCCESS);
4451 if (!ML_(fd_allowed)(RES, "open", tid, True)) {
4452 VG_(close)(RES);
4453 SET_STATUS_Failure( VKI_EMFILE );
4454 } else {
4455 if (VG_(clo_track_fds))
4456 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
4460 PRE(sys_read)
4462 *flags |= SfMayBlock;
4463 PRINT("sys_read ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4464 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4465 PRE_REG_READ3(ssize_t, "read",
4466 int, fd, char *, buf, vki_size_t, count);
4468 if (!ML_(fd_allowed)(ARG1, "read", tid, False))
4469 SET_STATUS_Failure( VKI_EBADF );
4470 else
4471 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
4474 POST(sys_read)
4476 vg_assert(SUCCESS);
4477 POST_MEM_WRITE( ARG2, RES );
4480 PRE(sys_write)
4482 Bool ok;
4483 *flags |= SfMayBlock;
4484 PRINT("sys_write ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4485 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4486 PRE_REG_READ3(ssize_t, "write",
4487 unsigned int, fd, const char *, buf, vki_size_t, count);
4488 /* check to see if it is allowed. If not, try for an exemption from
4489 --sim-hints=enable-outer (used for self hosting). */
4490 ok = ML_(fd_allowed)(ARG1, "write", tid, False);
4491 if (!ok && ARG1 == 2/*stderr*/
4492 && SimHintiS(SimHint_enable_outer, VG_(clo_sim_hints)))
4493 ok = True;
4494 #if defined(VGO_solaris)
4495 if (!ok && VG_(vfork_fildes_addr) != NULL
4496 && *VG_(vfork_fildes_addr) >= 0 && *VG_(vfork_fildes_addr) == ARG1)
4497 ok = True;
4498 #endif
4499 if (!ok)
4500 SET_STATUS_Failure( VKI_EBADF );
4501 else
4502 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
4505 PRE(sys_creat)
4507 *flags |= SfMayBlock;
4508 PRINT("sys_creat ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
4509 (HChar*)(Addr)ARG1, SARG2);
4510 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
4511 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
4514 POST(sys_creat)
4516 vg_assert(SUCCESS);
4517 if (!ML_(fd_allowed)(RES, "creat", tid, True)) {
4518 VG_(close)(RES);
4519 SET_STATUS_Failure( VKI_EMFILE );
4520 } else {
4521 if (VG_(clo_track_fds))
4522 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
4526 PRE(sys_poll)
4528 /* struct pollfd {
4529 int fd; -- file descriptor
4530 short events; -- requested events
4531 short revents; -- returned events
4533 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
4535 UInt i;
4536 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
4537 *flags |= SfMayBlock;
4538 PRINT("sys_poll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )\n",
4539 ARG1, ARG2, SARG3);
4540 PRE_REG_READ3(long, "poll",
4541 struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout);
4543 for (i = 0; i < ARG2; i++) {
4544 PRE_MEM_READ( "poll(ufds.fd)",
4545 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
4546 if (ML_(safe_to_deref)(&ufds[i].fd, sizeof(ufds[i].fd)) && ufds[i].fd >= 0) {
4547 PRE_MEM_READ( "poll(ufds.events)",
4548 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
4550 PRE_MEM_WRITE( "poll(ufds.revents)",
4551 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
4555 POST(sys_poll)
4557 if (SUCCESS) {
4558 UInt i;
4559 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
4560 for (i = 0; i < ARG2; i++)
4561 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
4565 PRE(sys_readlink)
4567 FUSE_COMPATIBLE_MAY_BLOCK();
4568 Word saved = SYSNO;
4570 PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )",
4571 ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3);
4572 PRE_REG_READ3(long, "readlink",
4573 const char *, path, char *, buf, int, bufsiz);
4574 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4575 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
4579 #if defined(VGO_linux) || defined(VGO_solaris)
4580 #if defined(VGO_linux)
4581 #define PID_EXEPATH "/proc/%d/exe"
4582 #define SELF_EXEPATH "/proc/self/exe"
4583 #define SELF_EXEFD "/proc/self/fd/%d"
4584 #elif defined(VGO_solaris)
4585 #define PID_EXEPATH "/proc/%d/path/a.out"
4586 #define SELF_EXEPATH "/proc/self/path/a.out"
4587 #define SELF_EXEFD "/proc/self/path/%d"
4588 #endif
4590 * Handle the case where readlink is looking at /proc/self/exe or
4591 * /proc/<pid>/exe, or equivalent on Solaris.
4593 HChar name[30]; // large enough
4594 HChar* arg1s = (HChar*) (Addr)ARG1;
4595 VG_(sprintf)(name, PID_EXEPATH, VG_(getpid)());
4596 if (ML_(safe_to_deref)(arg1s, 1)
4597 && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, SELF_EXEPATH))) {
4598 VG_(sprintf)(name, SELF_EXEFD, VG_(cl_exec_fd));
4599 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name,
4600 ARG2, ARG3));
4601 } else
4602 #endif
4604 /* Normal case */
4605 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
4609 if (SUCCESS && RES > 0)
4610 POST_MEM_WRITE( ARG2, RES );
4613 PRE(sys_readv)
4615 Int i;
4616 struct vki_iovec * vec;
4617 char buf[sizeof("readv(vector[])") + 11];
4618 *flags |= SfMayBlock;
4619 PRINT("sys_readv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4620 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4621 PRE_REG_READ3(ssize_t, "readv",
4622 unsigned long, fd, const struct iovec *, vector,
4623 unsigned long, count);
4624 if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
4625 SET_STATUS_Failure( VKI_EBADF );
4626 } else {
4627 if ((Int)ARG3 >= 0)
4628 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
4630 if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) {
4631 vec = (struct vki_iovec *)(Addr)ARG2;
4632 for (i = 0; i < (Int)ARG3; i++) {
4633 VG_(sprintf)(buf, "readv(vector[%d])", i);
4634 PRE_MEM_WRITE(buf, (Addr)vec[i].iov_base, vec[i].iov_len );
4640 POST(sys_readv)
4642 vg_assert(SUCCESS);
4643 if (RES > 0) {
4644 Int i;
4645 struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
4646 Int remains = RES;
4648 /* RES holds the number of bytes read. */
4649 for (i = 0; i < (Int)ARG3; i++) {
4650 Int nReadThisBuf = vec[i].iov_len;
4651 if (nReadThisBuf > remains) nReadThisBuf = remains;
4652 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4653 remains -= nReadThisBuf;
4654 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4659 PRE(sys_rename)
4661 FUSE_COMPATIBLE_MAY_BLOCK();
4662 PRINT("sys_rename ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )", ARG1,
4663 (char*)(Addr)ARG1,ARG2,(char*)(Addr)ARG2);
4664 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
4665 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4666 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
4669 PRE(sys_rmdir)
4671 *flags |= SfMayBlock;
4672 PRINT("sys_rmdir ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
4673 PRE_REG_READ1(long, "rmdir", const char *, pathname);
4674 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
4677 PRE(sys_select)
4679 *flags |= SfMayBlock;
4680 PRINT("sys_select ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4681 FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4, ARG5);
4682 PRE_REG_READ5(long, "select",
4683 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4684 vki_fd_set *, exceptfds, struct vki_timeval *, timeout);
4685 // XXX: this possibly understates how much memory is read.
4686 if (ARG2 != 0)
4687 PRE_MEM_READ( "select(readfds)",
4688 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4689 if (ARG3 != 0)
4690 PRE_MEM_READ( "select(writefds)",
4691 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4692 if (ARG4 != 0)
4693 PRE_MEM_READ( "select(exceptfds)",
4694 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4695 if (ARG5 != 0)
4696 PRE_timeval_READ( "select(timeout)", (Addr)ARG5 );
4699 PRE(sys_setgid)
4701 PRINT("sys_setgid ( %" FMT_REGWORD "u )", ARG1);
4702 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
4705 PRE(sys_setsid)
4707 PRINT("sys_setsid ( )");
4708 PRE_REG_READ0(long, "setsid");
4711 PRE(sys_setgroups)
4713 PRINT("setgroups ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
4714 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
4715 if (ARG1 > 0)
4716 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
4719 PRE(sys_setpgid)
4721 PRINT("setpgid ( %ld, %ld )", SARG1, SARG2);
4722 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
4725 PRE(sys_setregid)
4727 PRINT("sys_setregid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
4728 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
4731 PRE(sys_setreuid)
4733 PRINT("sys_setreuid ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
4734 ARG1, ARG2);
4735 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
4738 PRE(sys_setrlimit)
4740 UWord arg1 = ARG1;
4741 PRINT("sys_setrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
4742 PRE_REG_READ2(long, "setrlimit",
4743 unsigned int, resource, struct rlimit *, rlim);
4744 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
4746 #ifdef _RLIMIT_POSIX_FLAG
4747 // Darwin will sometimes set _RLIMIT_POSIX_FLAG on setrlimit calls.
4748 // Unset it here to make the if statements below work correctly.
4749 arg1 &= ~_RLIMIT_POSIX_FLAG;
4750 #endif
4752 if (!VG_(am_is_valid_for_client)(ARG2, sizeof(struct vki_rlimit),
4753 VKI_PROT_READ)) {
4754 SET_STATUS_Failure( VKI_EFAULT );
4756 else if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4757 > ((struct vki_rlimit *)(Addr)ARG2)->rlim_max) {
4758 #if defined(VGO_freebsd)
4759 SET_STATUS_Failure( VKI_EPERM );
4760 #else
4761 SET_STATUS_Failure( VKI_EINVAL );
4762 #endif
4764 else if (arg1 == VKI_RLIMIT_NOFILE) {
4765 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4766 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max != VG_(fd_hard_limit)) {
4767 SET_STATUS_Failure( VKI_EPERM );
4769 else {
4770 VG_(fd_soft_limit) = ((struct vki_rlimit *)(Addr)ARG2)->rlim_cur;
4771 SET_STATUS_Success( 0 );
4774 else if (arg1 == VKI_RLIMIT_DATA) {
4775 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4776 > VG_(client_rlimit_data).rlim_max ||
4777 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max
4778 > VG_(client_rlimit_data).rlim_max) {
4779 SET_STATUS_Failure( VKI_EPERM );
4781 else {
4782 VG_(client_rlimit_data) = *(struct vki_rlimit *)(Addr)ARG2;
4783 SET_STATUS_Success( 0 );
4786 else if (arg1 == VKI_RLIMIT_STACK && tid == 1) {
4787 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4788 > VG_(client_rlimit_stack).rlim_max ||
4789 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max
4790 > VG_(client_rlimit_stack).rlim_max) {
4791 SET_STATUS_Failure( VKI_EPERM );
4793 else {
4794 /* Change the value of client_stack_szB to the rlim_cur value but
4795 only if it is smaller than the size of the allocated stack for the
4796 client.
4797 TODO: All platforms should set VG_(clstk_max_size) as part of their
4798 setup_client_stack(). */
4799 if ((VG_(clstk_max_size) == 0)
4800 || (((struct vki_rlimit *) (Addr)ARG2)->rlim_cur <= VG_(clstk_max_size)))
4801 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)(Addr)ARG2)->rlim_cur;
4803 VG_(client_rlimit_stack) = *(struct vki_rlimit *)(Addr)ARG2;
4804 SET_STATUS_Success( 0 );
4809 PRE(sys_setuid)
4811 PRINT("sys_setuid ( %" FMT_REGWORD "u )", ARG1);
4812 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4815 #if !defined(VGP_nanomips_linux) && !defined(VGO_freebsd)
4816 PRE(sys_newstat)
4818 FUSE_COMPATIBLE_MAY_BLOCK();
4819 PRINT("sys_newstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4820 ARG1,(char*)(Addr)ARG1,ARG2);
4821 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
4822 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
4823 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
4826 POST(sys_newstat)
4828 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4830 #endif
4832 #if !defined(VGP_nanomips_linux)
4833 PRE(sys_statfs)
4835 FUSE_COMPATIBLE_MAY_BLOCK();
4836 PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4837 ARG1, (char*)(Addr)ARG1, ARG2);
4838 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
4839 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
4840 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
4842 POST(sys_statfs)
4844 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
4847 PRE(sys_statfs64)
4849 PRINT("sys_statfs64 ( %#" FMT_REGWORD "x(%s), %llu, %#" FMT_REGWORD "x )",
4850 ARG1, (char*)(Addr)ARG1, (ULong)ARG2, ARG3);
4851 PRE_REG_READ3(long, "statfs64",
4852 const char *, path, vki_size_t, size, struct statfs64 *, buf);
4853 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
4854 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
4856 POST(sys_statfs64)
4858 POST_MEM_WRITE( ARG3, ARG2 );
4860 #endif
4862 PRE(sys_symlink)
4864 *flags |= SfMayBlock;
4865 PRINT("sys_symlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )",
4866 ARG1, (char*)(Addr)ARG1, ARG2, (char*)(Addr)ARG2);
4867 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
4868 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
4869 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
4872 PRE(sys_time)
4874 /* time_t time(time_t *t); */
4875 PRINT("sys_time ( %#" FMT_REGWORD "x )",ARG1);
4876 PRE_REG_READ1(long, "time", int *, t);
4877 if (ARG1 != 0) {
4878 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
4882 POST(sys_time)
4884 if (ARG1 != 0) {
4885 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
4889 PRE(sys_times)
4891 PRINT("sys_times ( %#" FMT_REGWORD "x )", ARG1);
4892 PRE_REG_READ1(long, "times", struct tms *, buf);
4893 if (ARG1 != 0) {
4894 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
4898 POST(sys_times)
4900 if (ARG1 != 0) {
4901 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
4905 PRE(sys_umask)
4907 PRINT("sys_umask ( %ld )", SARG1);
4908 PRE_REG_READ1(long, "umask", int, mask);
4911 PRE(sys_unlink)
4913 *flags |= SfMayBlock;
4914 PRINT("sys_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
4915 PRE_REG_READ1(long, "unlink", const char *, pathname);
4916 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
4919 #if !defined(VGO_freebsd)
4920 PRE(sys_newuname)
4922 PRINT("sys_newuname ( %#" FMT_REGWORD "x )", ARG1);
4923 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
4924 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
4927 POST(sys_newuname)
4929 if (ARG1 != 0) {
4930 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
4933 #endif
4935 PRE(sys_waitpid)
4937 *flags |= SfMayBlock;
4938 PRINT("sys_waitpid ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
4939 PRE_REG_READ3(long, "waitpid",
4940 vki_pid_t, pid, unsigned int *, status, int, options);
4942 if (ARG2 != (Addr)NULL)
4943 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
4946 POST(sys_waitpid)
4948 if (ARG2 != (Addr)NULL)
4949 POST_MEM_WRITE( ARG2, sizeof(int) );
4952 PRE(sys_wait4)
4954 *flags |= SfMayBlock;
4955 PRINT("sys_wait4 ( %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
4956 SARG1, ARG2, SARG3, ARG4);
4958 PRE_REG_READ4(long, "wait4",
4959 vki_pid_t, pid, unsigned int *, status, int, options,
4960 struct rusage *, rusage);
4961 if (ARG2 != (Addr)NULL)
4962 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
4963 if (ARG4 != (Addr)NULL)
4964 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
4967 POST(sys_wait4)
4969 if (ARG2 != (Addr)NULL)
4970 POST_MEM_WRITE( ARG2, sizeof(int) );
4971 if (ARG4 != (Addr)NULL)
4972 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
4975 PRE(sys_writev)
4977 Int i;
4978 struct vki_iovec * vec;
4979 char buf[sizeof("writev(vector[])") + 11];
4980 *flags |= SfMayBlock;
4981 PRINT("sys_writev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4982 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4983 PRE_REG_READ3(ssize_t, "writev",
4984 unsigned long, fd, const struct iovec *, vector,
4985 unsigned long, count);
4986 if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) {
4987 SET_STATUS_Failure( VKI_EBADF );
4988 } else {
4989 if ((Int)ARG3 >= 0)
4990 PRE_MEM_READ( "writev(vector)",
4991 ARG2, ARG3 * sizeof(struct vki_iovec) );
4993 if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) {
4994 vec = (struct vki_iovec *)(Addr)ARG2;
4995 for (i = 0; i < (Int)ARG3; i++) {
4996 VG_(sprintf)(buf, "writev(vector[%d])", i);
4997 PRE_MEM_READ( buf, (Addr)vec[i].iov_base, vec[i].iov_len );
5003 PRE(sys_utimes)
5005 FUSE_COMPATIBLE_MAY_BLOCK();
5006 PRINT("sys_utimes ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5007 ARG1, (char*)(Addr)ARG1, ARG2);
5008 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
5009 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5010 if (ARG2 != 0) {
5011 PRE_timeval_READ( "utimes(tvp[0])", (Addr)ARG2 );
5012 PRE_timeval_READ( "utimes(tvp[1])",
5013 (Addr)ARG2+sizeof(struct vki_timeval) );
5017 PRE(sys_acct)
5019 PRINT("sys_acct ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
5020 PRE_REG_READ1(long, "acct", const char *, filename);
5021 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
5024 PRE(sys_pause)
5026 *flags |= SfMayBlock;
5027 PRINT("sys_pause ( )");
5028 PRE_REG_READ0(long, "pause");
5031 PRE(sys_sigaltstack)
5033 PRINT("sigaltstack ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
5034 PRE_REG_READ2(int, "sigaltstack",
5035 const vki_stack_t *, ss, vki_stack_t *, oss);
5036 if (ARG1 != 0) {
5037 const vki_stack_t *ss = (vki_stack_t *)(Addr)ARG1;
5038 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_sp, sizeof(ss->ss_sp) );
5039 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_flags, sizeof(ss->ss_flags) );
5040 PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_size, sizeof(ss->ss_size) );
5042 if (ARG2 != 0) {
5043 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
5046 /* Be safe. */
5047 if (ARG1 && !ML_(safe_to_deref((void*)(Addr)ARG1, sizeof(vki_stack_t)))) {
5048 SET_STATUS_Failure(VKI_EFAULT);
5049 return;
5051 if (ARG2 && !ML_(safe_to_deref((void*)(Addr)ARG2, sizeof(vki_stack_t)))) {
5052 SET_STATUS_Failure(VKI_EFAULT);
5053 return;
5056 SET_STATUS_from_SysRes(
5057 VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)(Addr)ARG1,
5058 (vki_stack_t*)(Addr)ARG2)
5061 POST(sys_sigaltstack)
5063 vg_assert(SUCCESS);
5064 if (RES == 0 && ARG2 != 0)
5065 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
5068 PRE(sys_sethostname)
5070 PRINT("sys_sethostname ( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
5071 PRE_REG_READ2(long, "sethostname", char *, name, int, len);
5072 PRE_MEM_READ( "sethostname(name)", ARG1, ARG2 );
5075 #undef PRE
5076 #undef POST
5078 #endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
5080 /*--------------------------------------------------------------------*/
5081 /*--- end ---*/
5082 /*--------------------------------------------------------------------*/