Command line help - demangling isn't just for C++
[valgrind.git] / coregrind / m_syswrap / syswrap-generic.c
blobbfe4c6fe06b12105fb64a9e62fedb1cc98b8191a
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;
557 Int ML_(get_fd_count)(void)
559 return fd_count;
562 /* Close_range caller might want to close very wide range of file descriptors,
563 up to ~0U. We want to avoid iterating through such a range in a normal
564 close_range, just up to any open file descriptor. Also, unlike
565 record_fd_close_range, we assume the user might deliberately double closes
566 any file descriptors in the range, so don't warn about double close here. */
567 void ML_(record_fd_close_range)(ThreadId tid, Int from_fd)
569 OpenFd *i = allocated_fds;
571 if (from_fd >= VG_(fd_hard_limit))
572 return; /* Valgrind internal */
574 while(i) {
575 // Assume the user doesn't want a warning if this came from
576 // close_range. Just record the file descriptors not yet closed here.
577 if (i->fd >= from_fd && !i->fd_closed
578 && i->fd != VG_(log_output_sink).fd
579 && i->fd != VG_(xml_output_sink).fd) {
580 i->fd_closed = True;
581 i->where_closed = ((tid == -1)
582 ? NULL
583 : VG_(record_ExeContext)(tid,
584 0/*first_ip_delta*/));
585 fd_count--;
587 i = i->next;
591 struct BadCloseExtra {
592 Int fd; /* The file descriptor */
593 HChar *pathname; /* NULL if not a regular file or unknown */
594 HChar *description; /* Description of the file descriptor
595 might include the pathname */
596 ExeContext *where_closed; /* record the last close of fd */
597 ExeContext *where_opened; /* recordwhere the fd was opened */
600 struct FdBadUse {
601 Int fd; /* The file descriptor */
602 HChar *pathname; /* NULL if not a regular file or unknown */
603 HChar *description; /* Description of the file descriptor
604 might include the pathname */
605 ExeContext *where_closed; /* record the last close of fd */
606 ExeContext *where_opened; /* recordwhere the fd was opened */
609 struct NotClosedExtra {
610 Int fd;
611 HChar *pathname;
612 HChar *description;
615 /* Note the fact that a file descriptor was just closed. */
616 void ML_(record_fd_close)(ThreadId tid, Int fd)
618 OpenFd *i = allocated_fds;
620 if (fd >= VG_(fd_hard_limit))
621 return; /* Valgrind internal */
623 while(i) {
624 if (i->fd == fd) {
625 if (i->fd_closed) {
626 struct BadCloseExtra bce;
627 bce.fd = i->fd;
628 bce.pathname = i->pathname;
629 bce.description = i->description;
630 bce.where_opened = i->where;
631 bce.where_closed = i->where_closed;
632 VG_(maybe_record_error)(tid, FdBadClose, 0,
633 "file descriptor already closed", &bce);
634 } else {
635 i->fd_closed = True;
636 i->where_closed = ((tid == -1)
637 ? NULL
638 : VG_(record_ExeContext)(tid,
639 0/*first_ip_delta*/));
640 /* Record path/socket name, etc. In case we want to print it later,
641 for example for double close. Note that record_fd_close is
642 actually called from the PRE syscall handler, so the file
643 description is about to be closed, but hasn't yet at this
644 point. */
645 if (!i->pathname) {
646 Int val;
647 Int len = sizeof(val);
648 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE,
649 &val, &len) == -1) {
650 HChar *pathname = VG_(malloc)("vg.record_fd_close.fd", 30);
651 VG_(snprintf)(pathname, 30, "file descriptor %d", i->fd);
652 i->description = pathname;
653 } else {
654 HChar *name = VG_(malloc)("vg.record_fd_close.sock", 256);
655 i->description = getsockdetails(i->fd, 256, name);
657 } else {
658 i->description = VG_(strdup)("vg.record_fd_close.path",
659 i->pathname);
661 fd_count--;
663 break;
665 i = i->next;
669 /* Note the fact that a file descriptor was just opened. If the
670 tid is -1, this indicates an inherited fd. If the pathname is NULL,
671 this either indicates a non-standard file (i.e. a pipe or socket or
672 some such thing) or that we don't know the filename. If the fd is
673 already open, then we're probably doing a dup2() to an existing fd,
674 so just overwrite the existing one. */
675 void ML_(record_fd_open_with_given_name)(ThreadId tid, Int fd,
676 const HChar *pathname)
678 OpenFd *i;
680 if (fd >= VG_(fd_hard_limit))
681 return; /* Valgrind internal */
683 /* Check to see if this fd is already open (or closed, we will just
684 override it. */
685 i = allocated_fds;
686 while (i) {
687 if (i->fd == fd) {
688 if (i->pathname) {
689 VG_(free)(i->pathname);
690 i->pathname = NULL;
692 if (i->description) {
693 VG_(free)(i->description);
694 i->description = NULL;
696 if (i->fd_closed) /* now we will open it. */
697 fd_count++;
698 break;
700 i = i->next;
703 /* Not already one: allocate an OpenFd */
704 if (i == NULL) {
705 i = VG_(malloc)("syswrap.rfdowgn.1", sizeof(OpenFd));
707 i->prev = NULL;
708 i->next = allocated_fds;
709 if(allocated_fds) allocated_fds->prev = i;
710 allocated_fds = i;
711 fd_count++;
714 i->fd = fd;
715 i->pathname = VG_(strdup)("syswrap.rfdowgn.2", pathname);
716 i->description = NULL; /* Only set on close. */
717 i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid, 0/*first_ip_delta*/);
718 i->fd_closed = False;
719 i->where_closed = NULL;
722 // Record opening of an fd, and find its name.
723 void ML_(record_fd_open_named)(ThreadId tid, Int fd)
725 const HChar* buf;
726 const HChar* name;
727 if (VG_(resolve_filename)(fd, &buf))
728 name = buf;
729 else
730 name = NULL;
732 ML_(record_fd_open_with_given_name)(tid, fd, name);
735 // Record opening of a nameless fd.
736 void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
738 ML_(record_fd_open_with_given_name)(tid, fd, NULL);
741 // Return if a given file descriptor is already recorded.
742 Bool ML_(fd_recorded)(Int fd)
744 OpenFd *i = allocated_fds;
745 while (i) {
746 if (i->fd == fd) {
747 if (i->fd_closed)
748 return False;
749 else
750 return True;
752 i = i->next;
754 return False;
757 /* Returned string must not be modified nor free'd. */
758 const HChar *ML_(find_fd_recorded_by_fd)(Int fd)
760 OpenFd *i = allocated_fds;
762 while (i) {
763 if (i->fd == fd) {
764 if (i->fd_closed)
765 return NULL;
766 else
767 return i->pathname;
769 i = i->next;
772 return NULL;
775 static
776 HChar *unix_to_name(struct vki_sockaddr_un *sa, UInt len, HChar *name)
778 if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') {
779 VG_(sprintf)(name, "<unknown>");
780 } else {
781 VG_(sprintf)(name, "%s", sa->sun_path);
784 return name;
787 static
788 HChar *inet_to_name(struct vki_sockaddr_in *sa, UInt len, HChar *name)
790 if (sa == NULL || len == 0) {
791 VG_(sprintf)(name, "<unknown>");
792 } else if (sa->sin_port == 0) {
793 VG_(sprintf)(name, "<unbound>");
794 } else {
795 UInt addr = VG_(ntohl)(sa->sin_addr.s_addr);
796 VG_(sprintf)(name, "%u.%u.%u.%u:%u",
797 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
798 (addr>>8) & 0xFF, addr & 0xFF,
799 VG_(ntohs)(sa->sin_port));
802 return name;
805 static
806 void inet6_format(HChar *s, const UChar ip[16])
808 static const unsigned char V4mappedprefix[12] = {0,0,0,0,0,0,0,0,0,0,0xff,0xff};
810 if (!VG_(memcmp)(ip, V4mappedprefix, 12)) {
811 const struct vki_in_addr *sin_addr =
812 (const struct vki_in_addr *)(ip + 12);
813 UInt addr = VG_(ntohl)(sin_addr->s_addr);
815 VG_(sprintf)(s, "::ffff:%u.%u.%u.%u",
816 (addr>>24) & 0xFF, (addr>>16) & 0xFF,
817 (addr>>8) & 0xFF, addr & 0xFF);
818 } else {
819 Bool compressing = False;
820 Bool compressed = False;
821 Int len = 0;
822 Int i;
824 for (i = 0; i < 16; i += 2) {
825 UInt word = ((UInt)ip[i] << 8) | (UInt)ip[i+1];
826 if (word == 0 && !compressed) {
827 compressing = True;
828 } else {
829 if (compressing) {
830 compressing = False;
831 compressed = True;
832 s[len++] = ':';
834 if (i > 0) {
835 s[len++] = ':';
837 len += VG_(sprintf)(s + len, "%x", word);
841 if (compressing) {
842 s[len++] = ':';
843 s[len++] = ':';
846 s[len++] = 0;
849 return;
852 static
853 HChar *inet6_to_name(struct vki_sockaddr_in6 *sa, UInt len, HChar *name)
855 if (sa == NULL || len == 0) {
856 VG_(sprintf)(name, "<unknown>");
857 } else if (sa->sin6_port == 0) {
858 VG_(sprintf)(name, "<unbound>");
859 } else {
860 HChar addr[100]; // large enough
861 inet6_format(addr, (void *)&(sa->sin6_addr));
862 VG_(sprintf)(name, "[%s]:%u", addr, VG_(ntohs)(sa->sin6_port));
865 return name;
869 * Try get some details about a socket.
870 * Returns the given BUF with max length LEN.
872 static
873 HChar *getsockdetails(Int fd, UInt len, HChar *buf)
875 union u {
876 struct vki_sockaddr a;
877 struct vki_sockaddr_in in;
878 struct vki_sockaddr_in6 in6;
879 struct vki_sockaddr_un un;
880 } laddr;
881 Int llen;
883 llen = sizeof(laddr);
884 VG_(memset)(&laddr, 0, llen);
886 if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) {
887 switch(laddr.a.sa_family) {
888 case VKI_AF_INET: {
889 HChar lname[32]; // large enough
890 HChar pname[32]; // large enough
891 struct vki_sockaddr_in paddr;
892 Int plen = sizeof(struct vki_sockaddr_in);
894 if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
895 VG_(snprintf)(buf, len, "AF_INET socket %d: %s <-> %s", fd,
896 inet_to_name(&(laddr.in), llen, lname),
897 inet_to_name(&paddr, plen, pname));
898 return buf;
899 } else {
900 VG_(snprintf)(buf, len, "AF_INET socket %d: %s <-> <unbound>",
901 fd, inet_to_name(&(laddr.in), llen, lname));
902 return buf;
905 case VKI_AF_INET6: {
906 HChar lname[128]; // large enough
907 HChar pname[128]; // large enough
908 struct vki_sockaddr_in6 paddr;
909 Int plen = sizeof(struct vki_sockaddr_in6);
911 if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) {
912 VG_(snprintf)(buf, len, "AF_INET6 socket %d: %s <-> %s", fd,
913 inet6_to_name(&(laddr.in6), llen, lname),
914 inet6_to_name(&paddr, plen, pname));
915 return buf;
916 } else {
917 VG_(snprintf)(buf, len, "AF_INET6 socket %d: %s <-> <unbound>",
918 fd, inet6_to_name(&(laddr.in6), llen, lname));
919 return buf;
922 case VKI_AF_UNIX: {
923 static char lname[256];
924 VG_(snprintf)(buf, len, "AF_UNIX socket %d: %s", fd,
925 unix_to_name(&(laddr.un), llen, lname));
926 return buf;
928 default:
929 VG_(snprintf)(buf, len, "pf-%d socket %d",
930 laddr.a.sa_family, fd);
931 return buf;
935 VG_(snprintf)(buf, len, "socket %d", fd);
936 return buf;
940 /* Dump out a summary, and a more detailed list, of open file descriptors. */
941 void VG_(show_open_fds) (const HChar* when)
943 OpenFd *i;
944 int non_std = 0;
946 for (i = allocated_fds; i; i = i->next) {
947 if (i->fd > 2 && i->fd_closed != True)
948 non_std++;
951 /* If we are running quiet and there are either no open file descriptors
952 or not tracking all fds, then don't report anything. */
953 if ((fd_count == 0
954 || ((non_std == 0) && (VG_(clo_track_fds) < 2)))
955 && (VG_(clo_verbosity) == 0))
956 return;
958 if (!VG_(clo_xml)) {
959 VG_(umsg)("FILE DESCRIPTORS: %d open (%d std) %s.\n",
960 fd_count, fd_count - non_std, when);
963 for (i = allocated_fds; i; i = i->next) {
964 if (i->fd_closed)
965 continue;
967 if (i->fd <= 2 && VG_(clo_track_fds) < 2)
968 continue;
970 struct NotClosedExtra nce;
971 /* The file descriptor was not yet closed, so the description field was
972 also not yet set. Set it now as if the file descriptor was closed at
973 this point. */
974 i->description = VG_(malloc)("vg.notclosedextra.descriptor", 256);
975 if (i->pathname) {
976 VG_(snprintf) (i->description, 256, "file descriptor %d: %s",
977 i->fd, i->pathname);
978 } else {
979 Int val;
980 Int len = sizeof(val);
982 if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len)
983 == -1) {
984 /* Don't want the : at the end in xml */
985 const HChar *colon = VG_(clo_xml) ? "" : ":";
986 VG_(sprintf)(i->description, "file descriptor %d%s", i->fd, colon);
987 } else {
988 getsockdetails(i->fd, 256, i->description);
992 nce.fd = i->fd;
993 nce.pathname = i->pathname;
994 nce.description = i->description;
995 VG_(unique_error) (1 /* Fake ThreadId */,
996 FdNotClosed,
997 0, /* Addr */
998 "Still Open file descriptor",
999 &nce, /* extra */
1000 i->where,
1001 True, /* print_error */
1002 False, /* allow_GDB_attach */
1003 True /* count_error */);
1007 if (!VG_(clo_xml))
1008 VG_(message)(Vg_UserMsg, "\n");
1011 /* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't
1012 have /proc support compiled in, or a non-Linux kernel), then we need to
1013 find out what file descriptors we inherited from our parent process the
1014 hard way - by checking each fd in turn. */
1015 static
1016 void init_preopened_fds_without_proc_self_fd(void)
1018 struct vki_rlimit lim;
1019 UInt count;
1020 Int i;
1022 if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
1023 /* Hmm. getrlimit() failed. Now we're screwed, so just choose
1024 an arbitrarily high number. 1024 happens to be the limit in
1025 the 2.4 Linux kernels. */
1026 count = 1024;
1027 } else {
1028 count = lim.rlim_cur;
1031 for (i = 0; i < count; i++)
1032 if (VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
1033 ML_(record_fd_open_named)(-1, i);
1036 /* Initialize the list of open file descriptors with the file descriptors
1037 we inherited from out parent process. */
1039 void VG_(init_preopened_fds)(void)
1041 // DDD: should probably use HAVE_PROC here or similar, instead.
1042 #if defined(VGO_linux)
1043 Int ret;
1044 struct vki_dirent64 d;
1045 SysRes f;
1047 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
1048 if (sr_isError(f)) {
1049 init_preopened_fds_without_proc_self_fd();
1050 return;
1053 while ((ret = VG_(getdents64)(sr_Res(f), &d, sizeof(d))) != 0) {
1054 if (ret == -1)
1055 goto out;
1057 if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
1058 HChar* s;
1059 Int fno = VG_(strtoll10)(d.d_name, &s);
1060 if (*s == '\0') {
1061 if (fno != sr_Res(f))
1062 if (VG_(clo_track_fds))
1063 ML_(record_fd_open_named)(-1, fno);
1064 } else {
1065 VG_(message)(Vg_DebugMsg,
1066 "Warning: invalid file name in /proc/self/fd: %s\n",
1067 d.d_name);
1071 VG_(lseek)(sr_Res(f), d.d_off, VKI_SEEK_SET);
1074 out:
1075 VG_(close)(sr_Res(f));
1077 #elif defined(VGO_darwin) || defined(VGO_freebsd)
1078 init_preopened_fds_without_proc_self_fd();
1080 #elif defined(VGO_solaris)
1081 Int ret;
1082 Char buf[VKI_MAXGETDENTS_SIZE];
1083 SysRes f;
1085 f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
1086 if (sr_isError(f)) {
1087 init_preopened_fds_without_proc_self_fd();
1088 return;
1091 while ((ret = VG_(getdents64)(sr_Res(f), (struct vki_dirent64 *) buf,
1092 sizeof(buf))) > 0) {
1093 Int i = 0;
1094 while (i < ret) {
1095 /* Proceed one entry. */
1096 struct vki_dirent64 *d = (struct vki_dirent64 *) (buf + i);
1097 if (VG_(strcmp)(d->d_name, ".") && VG_(strcmp)(d->d_name, "..")) {
1098 HChar *s;
1099 Int fno = VG_(strtoll10)(d->d_name, &s);
1100 if (*s == '\0') {
1101 if (fno != sr_Res(f))
1102 if (VG_(clo_track_fds))
1103 ML_(record_fd_open_named)(-1, fno);
1104 } else {
1105 VG_(message)(Vg_DebugMsg,
1106 "Warning: invalid file name in /proc/self/fd: %s\n",
1107 d->d_name);
1111 /* Move on the next entry. */
1112 i += d->d_reclen;
1116 VG_(close)(sr_Res(f));
1118 #else
1119 # error Unknown OS
1120 #endif
1123 Bool fd_eq_Error (VgRes res, const Error *e1, const Error *e2)
1125 // XXX should we compare the fds?
1126 return False;
1129 void fd_before_pp_Error (const Error *err)
1131 // Nothing to do here
1134 void fd_pp_Error (const Error *err)
1136 const Bool xml = VG_(clo_xml);
1137 const HChar* whatpre = VG_(clo_xml) ? " <what>" : "";
1138 const HChar* whatpost = VG_(clo_xml) ? "</what>" : "";
1139 const HChar* auxpre = VG_(clo_xml) ? " <auxwhat>" : " ";
1140 const HChar* auxpost = VG_(clo_xml) ? "</auxwhat>" : "";
1141 ExeContext *where = VG_(get_error_where)(err);
1142 if (VG_(get_error_kind)(err) == FdBadClose) {
1143 if (xml) VG_(emit)(" <kind>FdBadClose</kind>\n");
1144 struct BadCloseExtra *bce = (struct BadCloseExtra *)
1145 VG_(get_error_extra)(err);
1146 vg_assert(bce);
1147 if (xml) {
1148 VG_(emit)(" <fd>%d</fd>\n", bce->fd);
1149 if (bce->pathname)
1150 VG_(emit)(" <path>%s</path>\n", bce->pathname);
1152 VG_(emit)("%sFile descriptor %d: %s is already closed%s\n",
1153 whatpre, bce->fd, bce->description, whatpost);
1154 VG_(pp_ExeContext)( where );
1155 VG_(emit)("%sPreviously closed%s\n", auxpre, auxpost);
1156 VG_(pp_ExeContext)(bce->where_closed);
1157 VG_(emit)("%sOriginally opened%s\n", auxpre, auxpost);
1158 VG_(pp_ExeContext)(bce->where_opened);
1159 } else if (VG_(get_error_kind)(err) == FdNotClosed) {
1160 if (xml) VG_(emit)(" <kind>FdNotClosed</kind>\n");
1161 struct NotClosedExtra *nce = (struct NotClosedExtra *)
1162 VG_(get_error_extra)(err);
1163 if (xml) {
1164 VG_(emit)(" <fd>%d</fd>\n", nce->fd);
1165 if (nce->pathname)
1166 VG_(emit)(" <path>%s</path>\n", nce->pathname);
1168 VG_(emit)("%sOpen %s%s\n", whatpre, nce->description, whatpost);
1169 if (where != NULL) {
1170 VG_(pp_ExeContext)(where);
1171 if (!xml) VG_(message)(Vg_UserMsg, "\n");
1172 } else if (!xml) {
1173 VG_(message)(Vg_UserMsg, " <inherited from parent>\n");
1174 VG_(message)(Vg_UserMsg, "\n");
1176 } else if (VG_(get_error_kind)(err) == FdBadUse) {
1177 if (xml) VG_(emit)(" <kind>FdBadUse</kind>\n");
1178 struct FdBadUse *nce = (struct FdBadUse *)
1179 VG_(get_error_extra)(err);
1180 const char *error_string = VG_(get_error_string)(err);
1181 if (xml) {
1182 VG_(emit)(" <fd>%d</fd>\n", nce->fd);
1183 if (nce->pathname)
1184 VG_(emit)(" <path>%s</path>\n", nce->pathname);
1186 VG_(emit)("%sFile descriptor %d %s%s\n", whatpre, nce->fd,
1187 error_string, whatpost);
1188 /* If the file descriptor was never created we won't have
1189 where_closed and where_opened. Only print them in a
1190 use after close case. */
1191 if (nce->where_closed) {
1192 VG_(emit)("%sPreviously closed%s\n", auxpre, auxpost);
1193 VG_(pp_ExeContext)(nce->where_closed);
1195 if (nce->where_opened) {
1196 VG_(emit)("%sOriginally opened%s\n", auxpre, auxpost);
1197 VG_(pp_ExeContext)(nce->where_opened);
1199 VG_(pp_ExeContext)(where);
1200 } else {
1201 vg_assert2 (False, "Unknown error kind: %d",
1202 VG_(get_error_kind)(err));
1206 /* Called to see if there is any extra state to be saved with this
1207 error. Must return the size of the extra struct. */
1208 UInt fd_update_extra (const Error *err)
1210 if (VG_(get_error_kind)(err) == FdBadClose)
1211 return sizeof (struct BadCloseExtra);
1212 else if (VG_(get_error_kind)(err) == FdNotClosed)
1213 return sizeof (struct NotClosedExtra);
1214 else if (VG_(get_error_kind)(err) == FdBadUse)
1215 return sizeof (struct FdBadUse);
1216 else {
1217 vg_assert2 (False, "Unknown error kind: %d",
1218 VG_(get_error_kind)(err));
1222 static
1223 void pre_mem_read_sendmsg ( ThreadId tid, Bool read,
1224 const HChar *msg, Addr base, SizeT size )
1226 HChar outmsg[VG_(strlen)(msg) + 10]; // large enough
1227 VG_(sprintf)(outmsg, "sendmsg%s", msg);
1228 PRE_MEM_READ( outmsg, base, size );
1231 static
1232 void pre_mem_write_recvmsg ( ThreadId tid, Bool read,
1233 const HChar *msg, Addr base, SizeT size )
1235 HChar outmsg[VG_(strlen)(msg) + 10]; // large enough
1236 VG_(sprintf)(outmsg, "recvmsg%s", msg);
1237 if ( read )
1238 PRE_MEM_READ( outmsg, base, size );
1239 else
1240 PRE_MEM_WRITE( outmsg, base, size );
1243 static
1244 void post_mem_write_recvmsg ( ThreadId tid, Bool read,
1245 const HChar *fieldName, Addr base, SizeT size )
1247 if ( !read )
1248 POST_MEM_WRITE( base, size );
1251 static
1252 void msghdr_foreachfield (
1253 ThreadId tid,
1254 const HChar *name,
1255 struct vki_msghdr *msg,
1256 UInt length,
1257 void (*foreach_func)( ThreadId, Bool, const HChar *, Addr, SizeT ),
1258 Bool rekv /* "recv" apparently shadows some header decl on OSX108 */
1261 HChar fieldName[VG_(strlen)(name) + 32]; // large enough.
1262 Addr a;
1263 SizeT s;
1265 if ( !msg )
1266 return;
1268 VG_(sprintf) ( fieldName, "(%s)", name );
1270 /* FIELDPAIR helps the compiler do one call to foreach_func
1271 for consecutive (no holes) fields. */
1272 #define FIELDPAIR(f1,f2) \
1273 if (offsetof(struct vki_msghdr, f1) + sizeof(msg->f1) \
1274 == offsetof(struct vki_msghdr, f2)) \
1275 s += sizeof(msg->f2); \
1276 else { \
1277 foreach_func (tid, True, fieldName, a, s); \
1278 a = (Addr)&msg->f2; \
1279 s = sizeof(msg->f2); \
1282 a = (Addr)&msg->msg_name;
1283 s = sizeof(msg->msg_name);
1284 FIELDPAIR(msg_name, msg_namelen);
1285 FIELDPAIR(msg_namelen, msg_iov);
1286 FIELDPAIR(msg_iov, msg_iovlen);
1287 FIELDPAIR(msg_iovlen, msg_control);
1288 FIELDPAIR(msg_control, msg_controllen);
1289 foreach_func ( tid, True, fieldName, a, s);
1290 #undef FIELDPAIR
1292 /* msg_flags is completely ignored for send_mesg, recv_mesg doesn't read
1293 the field, but does write to it. */
1294 if ( rekv )
1295 foreach_func ( tid, False, fieldName, (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) );
1297 if ( ML_(safe_to_deref)(&msg->msg_name, sizeof (void *))
1298 && msg->msg_name ) {
1299 VG_(sprintf) ( fieldName, "(%s.msg_name)", name );
1300 foreach_func ( tid, False, fieldName,
1301 (Addr)msg->msg_name, msg->msg_namelen );
1304 if ( ML_(safe_to_deref)(&msg->msg_iov, sizeof (void *))
1305 && msg->msg_iov ) {
1306 struct vki_iovec *iov = msg->msg_iov;
1307 UInt i;
1309 if (ML_(safe_to_deref)(&msg->msg_iovlen, sizeof (UInt))) {
1310 VG_(sprintf) ( fieldName, "(%s.msg_iov)", name );
1311 foreach_func ( tid, True, fieldName, (Addr)iov,
1312 msg->msg_iovlen * sizeof( struct vki_iovec ) );
1314 for ( i = 0; i < msg->msg_iovlen && length > 0; ++i, ++iov ) {
1315 if (ML_(safe_to_deref)(&iov->iov_len, sizeof (UInt))) {
1316 UInt iov_len = iov->iov_len <= length ? iov->iov_len : length;
1317 VG_(sprintf) ( fieldName, "(%s.msg_iov[%u])", name, i );
1318 foreach_func ( tid, False, fieldName,
1319 (Addr)iov->iov_base, iov_len );
1320 length = length - iov_len;
1326 if ( ML_(safe_to_deref) (&msg->msg_control, sizeof (void *))
1327 && msg->msg_control ) {
1328 VG_(sprintf) ( fieldName, "(%s.msg_control)", name );
1329 foreach_func ( tid, False, fieldName,
1330 (Addr)msg->msg_control, msg->msg_controllen );
1335 static void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg)
1337 struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg);
1339 while (cm) {
1340 if (cm->cmsg_level == VKI_SOL_SOCKET
1341 && cm->cmsg_type == VKI_SCM_RIGHTS ) {
1342 Int *fds = (Int *) VKI_CMSG_DATA(cm);
1343 Int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr)))
1344 / sizeof(int);
1345 Int i;
1347 for (i = 0; i < fdc; i++)
1348 if(VG_(clo_track_fds))
1349 // XXX: must we check the range on these fds with
1350 // ML_(fd_allowed)()?
1351 ML_(record_fd_open_named)(tid, fds[i]);
1354 cm = VKI_CMSG_NXTHDR(msg, cm);
1358 /* GrP kernel ignores sa_len (at least on Darwin); this checks the rest */
1359 void ML_(pre_mem_read_sockaddr) ( ThreadId tid,
1360 const HChar *description,
1361 struct vki_sockaddr *sa, UInt salen )
1363 HChar outmsg[VG_(strlen)( description ) + 30]; // large enough
1364 struct vki_sockaddr_un* saun = (struct vki_sockaddr_un *)sa;
1365 struct vki_sockaddr_in* sin = (struct vki_sockaddr_in *)sa;
1366 struct vki_sockaddr_in6* sin6 = (struct vki_sockaddr_in6 *)sa;
1367 # ifdef VKI_AF_BLUETOOTH
1368 struct vki_sockaddr_rc* rc = (struct vki_sockaddr_rc *)sa;
1369 # endif
1370 # ifdef VKI_AF_NETLINK
1371 struct vki_sockaddr_nl* nl = (struct vki_sockaddr_nl *)sa;
1372 # endif
1374 /* NULL/zero-length sockaddrs are legal */
1375 if ( sa == NULL || salen == 0 ) return;
1377 VG_(sprintf) ( outmsg, description, "sa_family" );
1378 PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t));
1379 #if defined(VGO_freebsd)
1380 VG_(sprintf) ( outmsg, description, "sa_len" );
1381 PRE_MEM_READ( outmsg, (Addr) &sa->sa_len, sizeof(char));
1382 #endif
1384 /* Don't do any extra checking if we cannot determine the sa_family. */
1385 if (! ML_(safe_to_deref) (&sa->sa_family, sizeof(vki_sa_family_t)))
1386 return;
1388 switch (sa->sa_family) {
1390 case VKI_AF_UNIX:
1391 if (ML_(safe_to_deref) (&saun->sun_path, sizeof (Addr))) {
1392 VG_(sprintf) ( outmsg, description, "sun_path" );
1393 PRE_MEM_RASCIIZ( outmsg, (Addr) saun->sun_path );
1394 // GrP fixme max of sun_len-2? what about nul char?
1396 break;
1398 case VKI_AF_INET:
1399 VG_(sprintf) ( outmsg, description, "sin_port" );
1400 PRE_MEM_READ( outmsg, (Addr) &sin->sin_port, sizeof (sin->sin_port) );
1401 VG_(sprintf) ( outmsg, description, "sin_addr" );
1402 PRE_MEM_READ( outmsg, (Addr) &sin->sin_addr, sizeof (sin->sin_addr) );
1403 break;
1405 case VKI_AF_INET6:
1406 VG_(sprintf) ( outmsg, description, "sin6_port" );
1407 PRE_MEM_READ( outmsg,
1408 (Addr) &sin6->sin6_port, sizeof (sin6->sin6_port) );
1409 VG_(sprintf) ( outmsg, description, "sin6_flowinfo" );
1410 PRE_MEM_READ( outmsg,
1411 (Addr) &sin6->sin6_flowinfo, sizeof (sin6->sin6_flowinfo) );
1412 VG_(sprintf) ( outmsg, description, "sin6_addr" );
1413 PRE_MEM_READ( outmsg,
1414 (Addr) &sin6->sin6_addr, sizeof (sin6->sin6_addr) );
1415 VG_(sprintf) ( outmsg, description, "sin6_scope_id" );
1416 PRE_MEM_READ( outmsg,
1417 (Addr) &sin6->sin6_scope_id, sizeof (sin6->sin6_scope_id) );
1418 break;
1420 # ifdef VKI_AF_BLUETOOTH
1421 case VKI_AF_BLUETOOTH:
1422 VG_(sprintf) ( outmsg, description, "rc_bdaddr" );
1423 PRE_MEM_READ( outmsg, (Addr) &rc->rc_bdaddr, sizeof (rc->rc_bdaddr) );
1424 VG_(sprintf) ( outmsg, description, "rc_channel" );
1425 PRE_MEM_READ( outmsg, (Addr) &rc->rc_channel, sizeof (rc->rc_channel) );
1426 break;
1427 # endif
1429 # ifdef VKI_AF_NETLINK
1430 case VKI_AF_NETLINK:
1431 VG_(sprintf)(outmsg, description, "nl_pid");
1432 PRE_MEM_READ(outmsg, (Addr)&nl->nl_pid, sizeof(nl->nl_pid));
1433 VG_(sprintf)(outmsg, description, "nl_groups");
1434 PRE_MEM_READ(outmsg, (Addr)&nl->nl_groups, sizeof(nl->nl_groups));
1435 break;
1436 # endif
1438 # ifdef VKI_AF_UNSPEC
1439 case VKI_AF_UNSPEC:
1440 break;
1441 # endif
1443 default:
1444 /* No specific information about this address family.
1445 Let's just check the full data following the family.
1446 Note that this can give false positive if this (unknown)
1447 struct sockaddr_???? has padding bytes between its elements. */
1448 VG_(sprintf) ( outmsg, description, "sa_data" );
1449 PRE_MEM_READ( outmsg, (Addr)&sa->sa_family + sizeof(sa->sa_family),
1450 salen - sizeof(sa->sa_family));
1451 break;
1455 /* Dereference a pointer to a UInt. */
1456 static UInt deref_UInt ( ThreadId tid, Addr a, const HChar* s )
1458 UInt* a_p = (UInt*)a;
1459 PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) );
1460 if (a_p == NULL || ! ML_(safe_to_deref) (a_p, sizeof(UInt)))
1461 return 0;
1462 else
1463 return *a_p;
1466 void ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p,
1467 const HChar* buf_s, const HChar* buflen_s )
1469 if (VG_(tdict).track_pre_mem_write) {
1470 UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s);
1471 if (buflen_in > 0) {
1472 VG_(tdict).track_pre_mem_write(
1473 Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in );
1478 void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res,
1479 Addr buf_p, Addr buflen_p, const HChar* s )
1481 if (!sr_isError(res) && VG_(tdict).track_post_mem_write) {
1482 UInt buflen_out = deref_UInt( tid, buflen_p, s);
1483 if (buflen_out > 0 && buf_p != (Addr)NULL) {
1484 VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
1489 /* ---------------------------------------------------------------------
1490 Data seg end, for brk()
1491 ------------------------------------------------------------------ */
1493 /* +--------+------------+
1494 | anon | resvn |
1495 +--------+------------+
1497 ^ ^ ^
1498 | | boundary is page aligned
1499 | VG_(brk_limit) -- no alignment constraint
1500 VG_(brk_base) -- page aligned -- does not move
1502 Both the anon part and the reservation part are always at least
1503 one page.
1506 /* Set the new data segment end to NEWBRK. If this succeeds, return
1507 NEWBRK, else return the current data segment end. */
1509 static Addr do_brk ( Addr newbrk, ThreadId tid )
1511 NSegment const* aseg;
1512 Addr newbrkP;
1513 SizeT delta;
1514 Bool debug = False;
1516 if (debug)
1517 VG_(printf)("\ndo_brk: brk_base=%#lx brk_limit=%#lx newbrk=%#lx\n",
1518 VG_(brk_base), VG_(brk_limit), newbrk);
1520 if (0) VG_(am_show_nsegments)(0, "in_brk");
1522 if (newbrk < VG_(brk_base))
1523 /* Clearly impossible. */
1524 goto bad;
1526 if (newbrk < VG_(brk_limit)) {
1527 /* shrinking the data segment. Be lazy and don't munmap the
1528 excess area. */
1529 NSegment const * seg = VG_(am_find_nsegment)(newbrk);
1530 vg_assert(seg);
1532 if (seg->hasT)
1533 VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk,
1534 "do_brk(shrink)" );
1535 /* Since we're being lazy and not unmapping pages, we have to
1536 zero out the area, so that if the area later comes back into
1537 circulation, it will be filled with zeroes, as if it really
1538 had been unmapped and later remapped. Be a bit paranoid and
1539 try hard to ensure we're not going to segfault by doing the
1540 write - check both ends of the range are in the same segment
1541 and that segment is writable. */
1542 NSegment const * seg2;
1544 seg2 = VG_(am_find_nsegment)( VG_(brk_limit) - 1 );
1545 vg_assert(seg2);
1547 if (seg == seg2 && seg->hasW)
1548 VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk );
1550 VG_(brk_limit) = newbrk;
1551 return newbrk;
1554 /* otherwise we're expanding the brk segment. */
1555 if (VG_(brk_limit) > VG_(brk_base))
1556 aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 );
1557 else
1558 aseg = VG_(am_find_nsegment)( VG_(brk_limit) );
1560 /* These should be assured by setup_client_dataseg in m_main. */
1561 vg_assert(aseg);
1562 vg_assert(aseg->kind == SkAnonC);
1564 if (newbrk <= aseg->end + 1) {
1565 /* still fits within the anon segment. */
1566 VG_(brk_limit) = newbrk;
1567 return newbrk;
1570 newbrkP = VG_PGROUNDUP(newbrk);
1571 delta = newbrkP - (aseg->end + 1);
1572 vg_assert(delta > 0);
1573 vg_assert(VG_IS_PAGE_ALIGNED(delta));
1575 Bool overflow = False;
1576 if (! VG_(am_extend_into_adjacent_reservation_client)( aseg->start, delta,
1577 &overflow)) {
1578 if (overflow) {
1579 static Bool alreadyComplained = False;
1580 if (!alreadyComplained) {
1581 alreadyComplained = True;
1582 if (VG_(clo_verbosity) > 0) {
1583 VG_(umsg)("brk segment overflow in thread #%u: "
1584 "can't grow to %#lx\n",
1585 tid, newbrkP);
1586 VG_(umsg)("(see section Limitations in user manual)\n");
1587 VG_(umsg)("NOTE: further instances of this message "
1588 "will not be shown\n");
1591 } else {
1592 if (VG_(clo_verbosity) > 0) {
1593 VG_(umsg)("Cannot map memory to grow brk segment in thread #%u "
1594 "to %#lx\n", tid, newbrkP);
1595 VG_(umsg)("(see section Limitations in user manual)\n");
1598 goto bad;
1601 VG_(brk_limit) = newbrk;
1602 return newbrk;
1604 bad:
1605 return VG_(brk_limit);
1608 static
1609 const OpenFd *ML_(find_OpenFd)(Int fd)
1611 OpenFd *i = allocated_fds;
1613 while (i) {
1614 if (i->fd == fd)
1615 return i;
1616 i = i->next;
1619 return NULL;
1623 /* ---------------------------------------------------------------------
1624 Vet file descriptors for sanity
1625 ------------------------------------------------------------------ */
1627 > - what does the "Bool soft" parameter mean?
1629 (Tom Hughes, 3 Oct 05):
1631 Whether or not to consider a file descriptor invalid if it is above
1632 the current soft limit.
1634 Basically if we are testing whether a newly created file descriptor is
1635 valid (in a post handler) then we set soft to true, and if we are
1636 testing whether a file descriptor that is about to be used (in a pre
1637 handler) is valid [viz, an already-existing fd] then we set it to false.
1639 The point is that if the (virtual) soft limit is lowered then any
1640 existing descriptors can still be read/written/closed etc (so long as
1641 they are below the valgrind reserved descriptors) but no new
1642 descriptors can be created above the new soft limit.
1644 (jrs 4 Oct 05: in which case, I've renamed it "isNewFd")
1647 /* Return true if we're allowed to use or create this fd */
1648 Bool ML_(fd_allowed)(Int fd, const HChar *syscallname, ThreadId tid,
1649 Bool isNewFd)
1651 Bool allowed = True;
1653 /* hard limits always apply */
1654 if (fd < 0 || fd >= VG_(fd_hard_limit))
1655 allowed = False;
1657 /* hijacking the output fds is never allowed */
1658 if (fd == VG_(log_output_sink).fd || fd == VG_(xml_output_sink).fd)
1659 allowed = False;
1661 /* if creating a new fd (rather than using an existing one), the
1662 soft limit must also be observed */
1663 if (isNewFd && fd >= VG_(fd_soft_limit))
1664 allowed = False;
1666 /* this looks like it ought to be included, but causes problems: */
1668 if (fd == 2 && VG_(debugLog_getLevel)() > 0)
1669 allowed = False;
1671 /* The difficulty is as follows: consider a program P which expects
1672 to be able to mess with (redirect) its own stderr (fd 2).
1673 Usually to deal with P we would issue command line flags to send
1674 logging somewhere other than stderr, so as not to disrupt P.
1675 The problem is that -d unilaterally hijacks stderr with no
1676 consultation with P. And so, if this check is enabled, P will
1677 work OK normally but fail if -d is issued.
1679 Basically -d is a hack and you take your chances when using it.
1680 It's very useful for low level debugging -- particularly at
1681 startup -- and having its presence change the behaviour of the
1682 client is exactly what we don't want. */
1684 /* croak? */
1685 if (VG_(clo_track_fds) && allowed
1686 && !isNewFd && (VG_(strcmp)("close", syscallname) != 0)) {
1687 const OpenFd *openbadfd = ML_(find_OpenFd)(fd);
1688 if (!openbadfd) {
1689 /* File descriptor which was never created (or inherited). */
1690 struct FdBadUse badfd;
1691 badfd.fd = fd;
1692 badfd.pathname = NULL;
1693 badfd.description = NULL;
1694 badfd.where_opened = NULL;
1695 badfd.where_closed = NULL;
1696 VG_(maybe_record_error)(tid, FdBadUse, 0,
1697 "was never created", &badfd);
1699 } else if (openbadfd->fd_closed) {
1700 /* Already closed file descriptor is being used. */
1701 struct FdBadUse badfd;
1702 badfd.fd = fd;
1703 badfd.pathname = openbadfd->pathname;
1704 badfd.description = openbadfd->description;
1705 badfd.where_opened = openbadfd->where;
1706 badfd.where_closed = openbadfd->where_closed;
1707 VG_(maybe_record_error)(tid, FdBadUse, 0,
1708 "was closed already", &badfd);
1711 if ((!allowed) && !isNewFd) {
1712 if (VG_(clo_track_fds)) {
1713 struct FdBadUse badfd;
1714 badfd.fd = fd;
1715 badfd.pathname = NULL;
1716 badfd.description = NULL;
1717 badfd.where_opened = NULL;
1718 badfd.where_closed = NULL;
1719 VG_(maybe_record_error)(tid, FdBadUse, 0,
1720 "Invalid file descriptor", &badfd);
1721 } else if (VG_(showing_core_warnings) ()) {
1722 // XXX legacy warnings, will be removed eventually
1723 VG_(message)(Vg_UserMsg,
1724 "Warning: invalid file descriptor %d in syscall %s()\n",
1725 fd, syscallname);
1728 if (VG_(showing_core_warnings) ()) {
1729 if (fd == VG_(log_output_sink).fd && VG_(log_output_sink).fd >= 0)
1730 VG_(message)(Vg_UserMsg,
1731 " Use --log-fd=<number> to select an alternative log fd.\n");
1732 if (fd == VG_(xml_output_sink).fd && VG_(xml_output_sink).fd >= 0)
1733 VG_(message)(Vg_UserMsg,
1734 " Use --xml-fd=<number> to select an alternative XML "
1735 "output fd.\n");
1737 // XXX This is the legacy warning, will be removed eventually
1738 if (VG_(clo_verbosity) > 1 && !VG_(clo_track_fds)) {
1739 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
1744 return allowed;
1748 /* ---------------------------------------------------------------------
1749 Deal with a bunch of socket-related syscalls
1750 ------------------------------------------------------------------ */
1752 /* ------ */
1754 void
1755 ML_(generic_PRE_sys_socketpair) ( ThreadId tid,
1756 UWord arg0, UWord arg1,
1757 UWord arg2, UWord arg3 )
1759 /* int socketpair(int d, int type, int protocol, int sv[2]); */
1760 PRE_MEM_WRITE( "socketcall.socketpair(sv)",
1761 arg3, 2*sizeof(int) );
1764 SysRes
1765 ML_(generic_POST_sys_socketpair) ( ThreadId tid,
1766 SysRes res,
1767 UWord arg0, UWord arg1,
1768 UWord arg2, UWord arg3 )
1770 SysRes r = res;
1771 Int fd1 = ((Int*)arg3)[0];
1772 Int fd2 = ((Int*)arg3)[1];
1773 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1774 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1775 if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) ||
1776 !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
1777 VG_(close)(fd1);
1778 VG_(close)(fd2);
1779 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1780 } else {
1781 POST_MEM_WRITE( arg3, 2*sizeof(int) );
1782 if (VG_(clo_track_fds)) {
1783 ML_(record_fd_open_nameless)(tid, fd1);
1784 ML_(record_fd_open_nameless)(tid, fd2);
1787 return r;
1790 /* ------ */
1792 SysRes
1793 ML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
1795 SysRes r = res;
1796 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1797 if (!ML_(fd_allowed)(sr_Res(res), "socket", tid, True)) {
1798 VG_(close)(sr_Res(res));
1799 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1800 } else {
1801 if (VG_(clo_track_fds))
1802 ML_(record_fd_open_nameless)(tid, sr_Res(res));
1804 return r;
1807 /* ------ */
1809 void
1810 ML_(generic_PRE_sys_bind) ( ThreadId tid,
1811 UWord arg0, UWord arg1, UWord arg2 )
1813 /* int bind(int sockfd, struct sockaddr *my_addr,
1814 int addrlen); */
1815 ML_(pre_mem_read_sockaddr) (
1816 tid, "socketcall.bind(my_addr.%s)",
1817 (struct vki_sockaddr *) arg1, arg2
1821 /* ------ */
1823 void
1824 ML_(generic_PRE_sys_accept) ( ThreadId tid,
1825 UWord arg0, UWord arg1, UWord arg2 )
1827 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1828 Addr addr_p = arg1;
1829 Addr addrlen_p = arg2;
1830 if (addr_p != (Addr)NULL)
1831 ML_(buf_and_len_pre_check) ( tid, addr_p, addrlen_p,
1832 "socketcall.accept(addr)",
1833 "socketcall.accept(addrlen_in)" );
1836 SysRes
1837 ML_(generic_POST_sys_accept) ( ThreadId tid,
1838 SysRes res,
1839 UWord arg0, UWord arg1, UWord arg2 )
1841 SysRes r = res;
1842 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1843 if (!ML_(fd_allowed)(sr_Res(res), "accept", tid, True)) {
1844 VG_(close)(sr_Res(res));
1845 r = VG_(mk_SysRes_Error)( VKI_EMFILE );
1846 } else {
1847 Addr addr_p = arg1;
1848 Addr addrlen_p = arg2;
1849 if (addr_p != (Addr)NULL)
1850 ML_(buf_and_len_post_check) ( tid, res, addr_p, addrlen_p,
1851 "socketcall.accept(addrlen_out)" );
1852 if (VG_(clo_track_fds))
1853 ML_(record_fd_open_nameless)(tid, sr_Res(res));
1855 return r;
1858 /* ------ */
1860 void
1861 ML_(generic_PRE_sys_sendto) ( ThreadId tid,
1862 UWord arg0, UWord arg1, UWord arg2,
1863 UWord arg3, UWord arg4, UWord arg5 )
1865 /* int sendto(int s, const void *msg, int len,
1866 unsigned int flags,
1867 const struct sockaddr *to, int tolen); */
1868 PRE_MEM_READ( "socketcall.sendto(msg)",
1869 arg1, /* msg */
1870 arg2 /* len */ );
1871 ML_(pre_mem_read_sockaddr) (
1872 tid, "socketcall.sendto(to.%s)",
1873 (struct vki_sockaddr *) arg4, arg5
1877 /* ------ */
1879 void
1880 ML_(generic_PRE_sys_send) ( ThreadId tid,
1881 UWord arg0, UWord arg1, UWord arg2 )
1883 /* int send(int s, const void *msg, size_t len, int flags); */
1884 PRE_MEM_READ( "socketcall.send(msg)",
1885 arg1, /* msg */
1886 arg2 /* len */ );
1890 /* ------ */
1892 void
1893 ML_(generic_PRE_sys_recvfrom) ( ThreadId tid,
1894 UWord arg0, UWord arg1, UWord arg2,
1895 UWord arg3, UWord arg4, UWord arg5 )
1897 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1898 struct sockaddr *from, int *fromlen); */
1899 Addr buf_p = arg1;
1900 Int len = arg2;
1901 Addr from_p = arg4;
1902 Addr fromlen_p = arg5;
1903 PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len );
1904 if (from_p != (Addr)NULL)
1905 ML_(buf_and_len_pre_check) ( tid, from_p, fromlen_p,
1906 "socketcall.recvfrom(from)",
1907 "socketcall.recvfrom(fromlen_in)" );
1910 void
1911 ML_(generic_POST_sys_recvfrom) ( ThreadId tid,
1912 SysRes res,
1913 UWord arg0, UWord arg1, UWord arg2,
1914 UWord arg3, UWord arg4, UWord arg5 )
1916 Addr buf_p = arg1;
1917 Int len = arg2;
1918 Addr from_p = arg4;
1919 Addr fromlen_p = arg5;
1921 vg_assert(!sr_isError(res)); /* guaranteed by caller */
1922 if (from_p != (Addr)NULL)
1923 ML_(buf_and_len_post_check) ( tid, res, from_p, fromlen_p,
1924 "socketcall.recvfrom(fromlen_out)" );
1925 POST_MEM_WRITE( buf_p, len );
1928 /* ------ */
1930 void
1931 ML_(generic_PRE_sys_recv) ( ThreadId tid,
1932 UWord arg0, UWord arg1, UWord arg2 )
1934 /* int recv(int s, void *buf, int len, unsigned int flags); */
1935 /* man 2 recv says:
1936 The recv call is normally used only on a connected socket
1937 (see connect(2)) and is identical to recvfrom with a NULL
1938 from parameter.
1940 PRE_MEM_WRITE( "socketcall.recv(buf)",
1941 arg1, /* buf */
1942 arg2 /* len */ );
1945 void
1946 ML_(generic_POST_sys_recv) ( ThreadId tid,
1947 UWord res,
1948 UWord arg0, UWord arg1, UWord arg2 )
1950 if (arg1 != 0) {
1951 POST_MEM_WRITE( arg1, /* buf */
1952 arg2 /* len */ );
1956 /* ------ */
1958 void
1959 ML_(generic_PRE_sys_connect) ( ThreadId tid,
1960 UWord arg0, UWord arg1, UWord arg2 )
1962 /* int connect(int sockfd,
1963 struct sockaddr *serv_addr, int addrlen ); */
1964 ML_(pre_mem_read_sockaddr) ( tid,
1965 "socketcall.connect(serv_addr.%s)",
1966 (struct vki_sockaddr *) arg1, arg2);
1969 /* ------ */
1971 void
1972 ML_(generic_PRE_sys_setsockopt) ( ThreadId tid,
1973 UWord arg0, UWord arg1, UWord arg2,
1974 UWord arg3, UWord arg4 )
1976 /* int setsockopt(int s, int level, int optname,
1977 const void *optval, int optlen); */
1978 PRE_MEM_READ( "socketcall.setsockopt(optval)",
1979 arg3, /* optval */
1980 arg4 /* optlen */ );
1983 /* ------ */
1985 void
1986 ML_(generic_PRE_sys_getsockname) ( ThreadId tid,
1987 UWord arg0, UWord arg1, UWord arg2 )
1989 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1990 Addr name_p = arg1;
1991 Addr namelen_p = arg2;
1992 /* Nb: name_p cannot be NULL */
1993 ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p,
1994 "socketcall.getsockname(name)",
1995 "socketcall.getsockname(namelen_in)" );
1998 void
1999 ML_(generic_POST_sys_getsockname) ( ThreadId tid,
2000 SysRes res,
2001 UWord arg0, UWord arg1, UWord arg2 )
2003 Addr name_p = arg1;
2004 Addr namelen_p = arg2;
2005 vg_assert(!sr_isError(res)); /* guaranteed by caller */
2006 ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
2007 "socketcall.getsockname(namelen_out)" );
2010 /* ------ */
2012 void
2013 ML_(generic_PRE_sys_getpeername) ( ThreadId tid,
2014 UWord arg0, UWord arg1, UWord arg2 )
2016 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
2017 Addr name_p = arg1;
2018 Addr namelen_p = arg2;
2019 /* Nb: name_p cannot be NULL */
2020 ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p,
2021 "socketcall.getpeername(name)",
2022 "socketcall.getpeername(namelen_in)" );
2025 void
2026 ML_(generic_POST_sys_getpeername) ( ThreadId tid,
2027 SysRes res,
2028 UWord arg0, UWord arg1, UWord arg2 )
2030 Addr name_p = arg1;
2031 Addr namelen_p = arg2;
2032 vg_assert(!sr_isError(res)); /* guaranteed by caller */
2033 ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p,
2034 "socketcall.getpeername(namelen_out)" );
2037 /* ------ */
2039 void
2040 ML_(generic_PRE_sys_sendmsg) ( ThreadId tid, const HChar *name,
2041 struct vki_msghdr *msg )
2043 msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_read_sendmsg, False );
2046 /* ------ */
2048 void
2049 ML_(generic_PRE_sys_recvmsg) ( ThreadId tid, const HChar *name,
2050 struct vki_msghdr *msg )
2052 msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_write_recvmsg, True );
2055 void
2056 ML_(generic_POST_sys_recvmsg) ( ThreadId tid, const HChar *name,
2057 struct vki_msghdr *msg, UInt length )
2059 msghdr_foreachfield( tid, name, msg, length, post_mem_write_recvmsg, True );
2060 check_cmsg_for_fds( tid, msg );
2064 /* ---------------------------------------------------------------------
2065 Deal with a bunch of IPC related syscalls
2066 ------------------------------------------------------------------ */
2068 /* ------ */
2070 void
2071 ML_(generic_PRE_sys_semop) ( ThreadId tid,
2072 UWord arg0, UWord arg1, UWord arg2 )
2074 /* int semop(int semid, struct sembuf *sops, unsigned nsops); */
2075 PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
2078 /* ------ */
2080 void
2081 ML_(generic_PRE_sys_semtimedop) ( ThreadId tid,
2082 UWord arg0, UWord arg1,
2083 UWord arg2, UWord arg3 )
2085 /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
2086 struct timespec *timeout); */
2087 PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) );
2088 if (arg3 != 0)
2089 PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) );
2092 /* ------ */
2094 static
2095 UInt get_sem_count( Int semid )
2097 union vki_semun arg;
2098 SysRes res;
2100 # if defined(__NR_semctl)
2101 # if defined(VGO_darwin)
2102 /* Darwin has no specific 64 bit semid_ds, but has __NR_semctl. */
2103 struct vki_semid_ds buf;
2104 arg.buf = &buf;
2105 # else
2106 struct vki_semid64_ds buf;
2107 arg.buf64 = &buf;
2108 # endif
2109 res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
2110 if (sr_isError(res))
2111 return 0;
2113 return buf.sem_nsems;
2114 # elif defined(__NR___semctl) /* FreeBSD */
2115 struct vki_semid_ds buf;
2116 arg.buf = &buf;
2117 res = VG_(do_syscall4)(__NR___semctl, semid, 0, VKI_IPC_STAT, (RegWord)&arg);
2119 if (sr_isError(res))
2120 return 0;
2122 // both clang-tidy and coverity complain about this but I think they are both wrong
2123 return buf.sem_nsems;
2124 # elif defined(__NR_semsys) /* Solaris */
2125 struct vki_semid_ds buf;
2126 arg.buf = &buf;
2127 res = VG_(do_syscall5)(__NR_semsys, VKI_SEMCTL, semid, 0, VKI_IPC_STAT,
2128 *(UWord *)&arg);
2129 if (sr_isError(res))
2130 return 0;
2132 return buf.sem_nsems;
2134 # else
2135 struct vki_semid_ds buf;
2136 arg.buf = &buf;
2137 res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
2138 VKI_IPC_STAT, (UWord)&arg);
2139 if (sr_isError(res))
2140 return 0;
2142 return buf.sem_nsems;
2143 # endif
2146 void
2147 ML_(generic_PRE_sys_semctl) ( ThreadId tid,
2148 UWord arg0, UWord arg1,
2149 UWord arg2, UWord arg3 )
2151 /* int semctl(int semid, int semnum, int cmd, ...); */
2152 union vki_semun arg = *(union vki_semun *)&arg3;
2153 UInt nsems;
2154 switch (arg2 /* cmd */) {
2155 #if defined(VKI_IPC_INFO)
2156 case VKI_IPC_INFO:
2157 case VKI_SEM_INFO:
2158 #if defined(VKI_IPC_64)
2159 case VKI_IPC_INFO|VKI_IPC_64:
2160 case VKI_SEM_INFO|VKI_IPC_64:
2161 #endif
2162 #if defined(VGO_freebsd)
2163 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
2164 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2165 #else
2166 PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)",
2167 (Addr)arg.buf, sizeof(struct vki_seminfo) );
2168 #endif
2169 break;
2170 #endif
2172 case VKI_IPC_STAT:
2173 #if defined(VKI_SEM_STAT)
2174 case VKI_SEM_STAT:
2175 #endif
2176 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
2177 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2178 break;
2180 #if defined(VKI_IPC_64)
2181 case VKI_IPC_STAT|VKI_IPC_64:
2182 #if defined(VKI_SEM_STAT)
2183 case VKI_SEM_STAT|VKI_IPC_64:
2184 #endif
2185 #endif
2186 #if defined(VKI_IPC_STAT64)
2187 case VKI_IPC_STAT64:
2188 #endif
2189 #if defined(VKI_IPC_64) || defined(VKI_IPC_STAT64)
2190 PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)",
2191 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2192 break;
2193 #endif
2195 case VKI_IPC_SET:
2196 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
2197 (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2198 break;
2200 #if defined(VKI_IPC_64)
2201 case VKI_IPC_SET|VKI_IPC_64:
2202 #endif
2203 #if defined(VKI_IPC_SET64)
2204 case VKI_IPC_SET64:
2205 #endif
2206 #if defined(VKI_IPC64) || defined(VKI_IPC_SET64)
2207 PRE_MEM_READ( "semctl(IPC_SET, arg.buf)",
2208 (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2209 break;
2210 #endif
2212 case VKI_GETALL:
2213 #if defined(VKI_IPC_64)
2214 case VKI_GETALL|VKI_IPC_64:
2215 #endif
2216 nsems = get_sem_count( arg0 );
2217 PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)",
2218 (Addr)arg.array, sizeof(unsigned short) * nsems );
2219 break;
2221 case VKI_SETALL:
2222 #if defined(VKI_IPC_64)
2223 case VKI_SETALL|VKI_IPC_64:
2224 #endif
2225 nsems = get_sem_count( arg0 );
2226 PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)",
2227 (Addr)arg.array, sizeof(unsigned short) * nsems );
2228 break;
2232 void
2233 ML_(generic_POST_sys_semctl) ( ThreadId tid,
2234 UWord res,
2235 UWord arg0, UWord arg1,
2236 UWord arg2, UWord arg3 )
2238 union vki_semun arg = *(union vki_semun *)&arg3;
2239 UInt nsems;
2240 switch (arg2 /* cmd */) {
2241 #if defined(VKI_IPC_INFO)
2242 case VKI_IPC_INFO:
2243 case VKI_SEM_INFO:
2244 #if defined(VKI_IPC_64)
2245 case VKI_IPC_INFO|VKI_IPC_64:
2246 case VKI_SEM_INFO|VKI_IPC_64:
2247 #endif
2248 #if defined(VGO_freebsd)
2249 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2250 #else
2251 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) );
2252 #endif
2253 break;
2254 #endif
2256 case VKI_IPC_STAT:
2257 #if defined(VKI_SEM_STAT)
2258 case VKI_SEM_STAT:
2259 #endif
2260 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) );
2261 break;
2263 #if defined(VKI_IPC_64)
2264 case VKI_IPC_STAT|VKI_IPC_64:
2265 case VKI_SEM_STAT|VKI_IPC_64:
2266 #endif
2267 #if defined(VKI_IPC_STAT64)
2268 case VKI_IPC_STAT64:
2269 #endif
2270 #if defined(VKI_IPC_64) || defined(VKI_IPC_STAT64)
2271 POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) );
2272 break;
2273 #endif
2275 case VKI_GETALL:
2276 #if defined(VKI_IPC_64)
2277 case VKI_GETALL|VKI_IPC_64:
2278 #endif
2279 nsems = get_sem_count( arg0 );
2280 POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems );
2281 break;
2285 /* ------ */
2287 /* ------ */
2289 static
2290 SizeT get_shm_size ( Int shmid )
2293 * The excluded platforms below gained direct shmctl in Linux 5.1. Keep
2294 * using ipc-multiplexed shmctl to keep compatibility with older kernel
2295 * versions.
2297 #if defined(__NR_shmctl) && \
2298 !defined(VGP_x86_linux) && !defined(VGP_mips32_linux) && \
2299 !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) && \
2300 !defined(VGP_ppc64le_linux) && !defined(VGP_s390x_linux)
2301 # ifdef VKI_IPC_64
2302 struct vki_shmid64_ds buf;
2304 * On Linux, the following ABIs use old shmid_ds by default with direct
2305 * shmctl and require IPC_64 for shmid64_ds (i.e. the direct syscall is
2306 * mapped to sys_old_shmctl):
2307 * alpha, arm, microblaze, mips n32/n64, xtensa
2308 * Other Linux ABIs use shmid64_ds by default and do not recognize IPC_64
2309 * with the direct shmctl syscall (but still recognize it for the
2310 * ipc-multiplexed version if that exists for the ABI).
2312 # if defined(VGO_linux) && !defined(VGP_arm_linux) && !defined(VGP_mips64_linux)
2313 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid,
2314 VKI_IPC_STAT, (UWord)&buf);
2315 # else
2316 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid,
2317 VKI_IPC_STAT|VKI_IPC_64, (UWord)&buf);
2318 # endif
2319 # else /* !def VKI_IPC_64 */
2320 struct vki_shmid_ds buf;
2321 SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
2322 # endif /* def VKI_IPC_64 */
2323 #elif defined(__NR_shmsys) /* Solaris */
2324 struct vki_shmid_ds buf;
2325 SysRes __res = VG_(do_syscall4)(__NR_shmsys, VKI_SHMCTL, shmid, VKI_IPC_STAT,
2326 (UWord)&buf);
2327 #else
2328 struct vki_shmid_ds buf;
2329 SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
2330 VKI_IPC_STAT, 0, (UWord)&buf);
2331 #endif
2332 if (sr_isError(__res))
2333 return 0;
2335 return (SizeT) buf.shm_segsz;
2338 UWord
2339 ML_(generic_PRE_sys_shmat) ( ThreadId tid,
2340 UWord arg0, UWord arg1, UWord arg2 )
2342 /* void *shmat(int shmid, const void *shmaddr, int shmflg); */
2343 SizeT segmentSize = get_shm_size ( arg0 );
2344 UWord tmp;
2345 Bool ok;
2346 if (arg1 == 0) {
2347 /* arm-linux only: work around the fact that
2348 VG_(am_get_advisory_client_simple) produces something that is
2349 VKI_PAGE_SIZE aligned, whereas what we want is something
2350 VKI_SHMLBA aligned, and VKI_SHMLBA >= VKI_PAGE_SIZE. Hence
2351 increase the request size by VKI_SHMLBA - VKI_PAGE_SIZE and
2352 then round the result up to the next VKI_SHMLBA boundary.
2353 See bug 222545 comment 15. So far, arm-linux is the only
2354 platform where this is known to be necessary. */
2355 vg_assert(VKI_SHMLBA >= VKI_PAGE_SIZE);
2356 if (VKI_SHMLBA > VKI_PAGE_SIZE) {
2357 segmentSize += VKI_SHMLBA - VKI_PAGE_SIZE;
2359 tmp = VG_(am_get_advisory_client_simple)(0, segmentSize, &ok);
2360 if (ok) {
2361 if (VKI_SHMLBA > VKI_PAGE_SIZE) {
2362 arg1 = VG_ROUNDUP(tmp, VKI_SHMLBA);
2363 } else {
2364 arg1 = tmp;
2368 else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat"))
2369 arg1 = 0;
2370 return arg1;
2373 void
2374 ML_(generic_POST_sys_shmat) ( ThreadId tid,
2375 UWord res,
2376 UWord arg0, UWord arg1, UWord arg2 )
2378 SizeT segmentSize = VG_PGROUNDUP(get_shm_size(arg0));
2379 if ( segmentSize > 0 ) {
2380 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
2381 Bool d;
2383 if (arg2 & VKI_SHM_RDONLY)
2384 prot &= ~VKI_PROT_WRITE;
2385 /* It isn't exactly correct to pass 0 for the fd and offset
2386 here. The kernel seems to think the corresponding section
2387 does have dev/ino numbers:
2389 04e52000-04ec8000 rw-s 00000000 00:06 1966090 /SYSV00000000 (deleted)
2391 However there is no obvious way to find them. In order to
2392 cope with the discrepancy, aspacem's sync checker omits the
2393 dev/ino correspondence check in cases where V does not know
2394 the dev/ino. */
2395 d = VG_(am_notify_client_shmat)( res, segmentSize, prot );
2397 /* we don't distinguish whether it's read-only or
2398 * read-write -- it doesn't matter really. */
2399 VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False,
2400 0/*di_handle*/ );
2401 if (d)
2402 VG_(discard_translations)( (Addr)res,
2403 (ULong)VG_PGROUNDUP(segmentSize),
2404 "ML_(generic_POST_sys_shmat)" );
2408 /* ------ */
2410 Bool
2411 ML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 )
2413 /* int shmdt(const void *shmaddr); */
2414 return ML_(valid_client_addr)(arg0, 1, tid, "shmdt");
2417 void
2418 ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
2420 NSegment const* s = VG_(am_find_nsegment)(arg0);
2422 if (s != NULL) {
2423 Addr s_start = s->start;
2424 SizeT s_len = s->end+1 - s->start;
2425 Bool d;
2427 vg_assert(s->kind == SkShmC);
2428 vg_assert(s->start == arg0);
2430 d = VG_(am_notify_munmap)(s_start, s_len);
2431 s = NULL; /* s is now invalid */
2432 VG_TRACK( die_mem_munmap, s_start, s_len );
2433 if (d)
2434 VG_(discard_translations)( s_start,
2435 (ULong)s_len,
2436 "ML_(generic_POST_sys_shmdt)" );
2439 /* ------ */
2441 void
2442 ML_(generic_PRE_sys_shmctl) ( ThreadId tid,
2443 UWord arg0, UWord arg1, UWord arg2 )
2445 /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
2446 switch (arg1 /* cmd */) {
2447 #if defined(VKI_IPC_INFO)
2448 case VKI_IPC_INFO:
2449 # if defined(VGO_freebsd)
2450 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2451 arg2, sizeof(struct vki_shmid_ds) );
2452 # else
2453 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2454 arg2, sizeof(struct vki_shminfo) );
2455 # endif
2456 break;
2457 #if defined(VKI_IPC_64)
2458 case VKI_IPC_INFO|VKI_IPC_64:
2459 PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)",
2460 arg2, sizeof(struct vki_shminfo64) );
2461 break;
2462 #endif
2463 #endif
2465 #if defined(VKI_SHM_INFO)
2466 case VKI_SHM_INFO:
2467 #if defined(VKI_IPC_64)
2468 case VKI_SHM_INFO|VKI_IPC_64:
2469 #endif
2470 PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)",
2471 arg2, sizeof(struct vki_shm_info) );
2472 break;
2473 #endif
2475 case VKI_IPC_STAT:
2476 #if defined(VKI_SHM_STAT)
2477 case VKI_SHM_STAT:
2478 #endif
2479 PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)",
2480 arg2, sizeof(struct vki_shmid_ds) );
2481 break;
2483 #if defined(VKI_IPC_64)
2484 case VKI_IPC_STAT|VKI_IPC_64:
2485 case VKI_SHM_STAT|VKI_IPC_64:
2486 PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)",
2487 arg2, sizeof(struct vki_shmid64_ds) );
2488 break;
2489 #endif
2491 case VKI_IPC_SET:
2492 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
2493 arg2, sizeof(struct vki_shmid_ds) );
2494 break;
2496 #if defined(VKI_IPC_64)
2497 case VKI_IPC_SET|VKI_IPC_64:
2498 PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)",
2499 arg2, sizeof(struct vki_shmid64_ds) );
2500 break;
2501 #endif
2505 void
2506 ML_(generic_POST_sys_shmctl) ( ThreadId tid,
2507 UWord res,
2508 UWord arg0, UWord arg1, UWord arg2 )
2510 switch (arg1 /* cmd */) {
2511 #if defined(VKI_IPC_INFO)
2512 case VKI_IPC_INFO:
2513 # if defined(VGO_freebsd)
2514 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
2515 # else
2516 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) );
2517 # endif
2518 break;
2519 #if defined(VKI_IPC_64)
2520 case VKI_IPC_INFO|VKI_IPC_64:
2521 POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) );
2522 break;
2523 #endif
2524 #endif
2526 #if defined(VKI_SHM_INFO)
2527 case VKI_SHM_INFO:
2528 case VKI_SHM_INFO|VKI_IPC_64:
2529 POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) );
2530 break;
2531 #endif
2533 case VKI_IPC_STAT:
2534 #if defined(VKI_SHM_STAT)
2535 case VKI_SHM_STAT:
2536 #endif
2537 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) );
2538 break;
2540 #if defined(VKI_IPC_64)
2541 case VKI_IPC_STAT|VKI_IPC_64:
2542 case VKI_SHM_STAT|VKI_IPC_64:
2543 POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) );
2544 break;
2545 #endif
2551 /* ---------------------------------------------------------------------
2552 Generic handler for mmap
2553 ------------------------------------------------------------------ */
2556 * Although mmap is specified by POSIX and the argument are generally
2557 * consistent across platforms the precise details of the low level
2558 * argument passing conventions differ. For example:
2560 * - On x86-linux there is mmap (aka old_mmap) which takes the
2561 * arguments in a memory block and the offset in bytes; and
2562 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
2563 * way and the offset in pages.
2565 * - On ppc32-linux there is mmap (aka sys_mmap) which takes the
2566 * arguments in the normal way and the offset in bytes; and
2567 * mmap2 (aka sys_mmap2) which takes the arguments in the normal
2568 * way and the offset in pages.
2570 * - On amd64-linux everything is simple and there is just the one
2571 * call, mmap (aka sys_mmap) which takes the arguments in the
2572 * normal way and the offset in bytes.
2574 * - On s390x-linux there is mmap (aka old_mmap) which takes the
2575 * arguments in a memory block and the offset in bytes. mmap2
2576 * is also available (but not exported via unistd.h) with
2577 * arguments in a memory block and the offset in pages.
2579 * To cope with all this we provide a generic handler function here
2580 * and then each platform implements one or more system call handlers
2581 * which call this generic routine after extracting and normalising
2582 * the arguments.
2585 SysRes
2586 ML_(generic_PRE_sys_mmap) ( ThreadId tid,
2587 UWord arg1, UWord arg2, UWord arg3,
2588 UWord arg4, UWord arg5, Off64T arg6 )
2590 Addr advised;
2591 SysRes sres;
2592 MapRequest mreq;
2593 Bool mreq_ok;
2595 # if defined(VGO_darwin)
2596 // Nb: we can't use this on Darwin, it has races:
2597 // * needs to RETRY if advisory succeeds but map fails
2598 // (could have been some other thread in a nonblocking call)
2599 // * needs to not use fixed-position mmap() on Darwin
2600 // (mmap will cheerfully smash whatever's already there, which might
2601 // be a new mapping from some other thread in a nonblocking call)
2602 VG_(core_panic)("can't use ML_(generic_PRE_sys_mmap) on Darwin");
2603 # endif
2605 if (arg2 == 0) {
2606 /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
2607 shall be established. */
2608 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2611 if (!VG_IS_PAGE_ALIGNED(arg1)) {
2612 /* zap any misaligned addresses. */
2613 /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
2614 to fail. Here, we catch them all. */
2615 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2618 if (!VG_IS_PAGE_ALIGNED(arg6)) {
2619 /* zap any misaligned offsets. */
2620 /* SuSV3 says: The off argument is constrained to be aligned and
2621 sized according to the value returned by sysconf() when
2622 passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
2623 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2626 /* Figure out what kind of allocation constraints there are
2627 (fixed/hint/any), and ask aspacem what we should do. */
2628 mreq.start = arg1;
2629 mreq.len = arg2;
2630 if (arg4 & VKI_MAP_FIXED) {
2631 mreq.rkind = MFixed;
2632 } else
2633 #if defined(VKI_MAP_ALIGN) /* Solaris specific */
2634 if (arg4 & VKI_MAP_ALIGN) {
2635 mreq.rkind = MAlign;
2636 if (mreq.start == 0) {
2637 mreq.start = VKI_PAGE_SIZE;
2639 /* VKI_MAP_FIXED and VKI_MAP_ALIGN don't like each other. */
2640 arg4 &= ~VKI_MAP_ALIGN;
2641 } else
2642 #endif
2643 if (arg1 != 0) {
2644 mreq.rkind = MHint;
2645 } else {
2646 mreq.rkind = MAny;
2649 /* Enquire ... */
2650 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2651 if (!mreq_ok) {
2652 /* Our request was bounced, so we'd better fail. */
2653 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2656 # if defined(VKI_MAP_32BIT)
2657 /* MAP_32BIT is royally unportable, so if the client asks for it, try our
2658 best to make it work (but without complexifying aspacemgr).
2659 If the user requested MAP_32BIT, the mmap-ed space must be in the
2660 first 2GB of the address space. So, return ENOMEM if aspacemgr
2661 advisory is above the first 2GB. If MAP_FIXED is also requested,
2662 MAP_32BIT has to be ignored.
2663 Assumption about aspacemgr behaviour: aspacemgr scans the address space
2664 from low addresses to find a free segment. No special effort is done
2665 to keep the first 2GB 'free' for this MAP_32BIT. So, this will often
2666 fail once the program has already allocated significant memory. */
2667 if ((arg4 & VKI_MAP_32BIT) && !(arg4 & VKI_MAP_FIXED)) {
2668 if (advised + arg2 >= 0x80000000)
2669 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
2671 # endif
2673 /* Otherwise we're OK (so far). Install aspacem's choice of
2674 address, and let the mmap go through. */
2675 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2676 arg4 | VKI_MAP_FIXED,
2677 arg5, arg6);
2679 # if defined(VKI_MAP_32BIT)
2680 /* No recovery trial if the advisory was not accepted. */
2681 if ((arg4 & VKI_MAP_32BIT) && !(arg4 & VKI_MAP_FIXED)
2682 && sr_isError(sres)) {
2683 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
2685 # endif
2687 /* A refinement: it may be that the kernel refused aspacem's choice
2688 of address. If we were originally asked for a hinted mapping,
2689 there is still a last chance: try again at any address.
2690 Hence: */
2691 if (mreq.rkind == MHint && sr_isError(sres)) {
2692 mreq.start = 0;
2693 mreq.len = arg2;
2694 mreq.rkind = MAny;
2695 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2696 if (!mreq_ok) {
2697 /* Our request was bounced, so we'd better fail. */
2698 return VG_(mk_SysRes_Error)( VKI_EINVAL );
2700 /* and try again with the kernel */
2701 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2702 arg4 | VKI_MAP_FIXED,
2703 arg5, arg6);
2706 /* Yet another refinement : sometimes valgrind chooses an address
2707 which is not acceptable by the kernel. This at least happens
2708 when mmap-ing huge pages, using the flag MAP_HUGETLB.
2709 valgrind aspacem does not know about huge pages, and modifying
2710 it to handle huge pages is not straightforward (e.g. need
2711 to understand special file system mount options).
2712 So, let's just redo an mmap, without giving any constraint to
2713 the kernel. If that succeeds, check with aspacem that the returned
2714 address is acceptable.
2715 This will give a similar effect as if the user would have
2716 hinted that address.
2717 The aspacem state will be correctly updated afterwards.
2718 We however cannot do this last refinement when the user asked
2719 for a fixed mapping, as the user asked a specific address. */
2720 if (sr_isError(sres) && !(arg4 & VKI_MAP_FIXED)) {
2721 advised = 0;
2722 /* try mmap with NULL address and without VKI_MAP_FIXED
2723 to let the kernel decide. */
2724 sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
2725 arg4,
2726 arg5, arg6);
2727 if (!sr_isError(sres)) {
2728 /* The kernel is supposed to know what it is doing, but let's
2729 do a last sanity check anyway, as if the chosen address had
2730 been initially hinted by the client. The whole point of this
2731 last try was to allow mmap of huge pages to succeed without
2732 making aspacem understand them, on the other hand the kernel
2733 does not know about valgrind reservations, so this mapping
2734 can end up in free space and reservations. */
2735 mreq.start = (Addr)sr_Res(sres);
2736 mreq.len = arg2;
2737 mreq.rkind = MHint;
2738 advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
2739 vg_assert(mreq_ok && advised == mreq.start);
2743 if (!sr_isError(sres)) {
2744 ULong di_handle;
2745 /* Notify aspacem. */
2746 notify_core_of_mmap(
2747 (Addr)sr_Res(sres), /* addr kernel actually assigned */
2748 arg2, /* length */
2749 arg3, /* prot */
2750 arg4, /* the original flags value */
2751 arg5, /* fd */
2752 arg6 /* offset */
2754 /* Load symbols? */
2755 di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres),
2756 False/*allow_SkFileV*/, (Int)arg5 );
2757 /* Notify the tool. */
2758 notify_tool_of_mmap(
2759 (Addr)sr_Res(sres), /* addr kernel actually assigned */
2760 arg2, /* length */
2761 arg3, /* prot */
2762 di_handle /* so the tool can refer to the read debuginfo later,
2763 if it wants. */
2767 /* Stay sane */
2768 if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED))
2769 vg_assert(sr_Res(sres) == arg1);
2771 return sres;
2775 /* ---------------------------------------------------------------------
2776 The Main Entertainment ... syscall wrappers
2777 ------------------------------------------------------------------ */
2779 /* Note: the PRE() and POST() wrappers are for the actual functions
2780 implementing the system calls in the OS kernel. These mostly have
2781 names like sys_write(); a few have names like old_mmap(). See the
2782 comment for ML_(syscall_table)[] for important info about the __NR_foo
2783 constants and their relationship to the sys_foo() functions.
2785 Some notes about names used for syscalls and args:
2786 - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid
2787 ambiguity.
2789 - For error messages, we generally use a somewhat generic name
2790 for the syscall (eg. "write" rather than "sys_write"). This should be
2791 good enough for the average user to understand what is happening,
2792 without confusing them with names like "sys_write".
2794 - Also, for error messages the arg names are mostly taken from the man
2795 pages (even though many of those man pages are really for glibc
2796 functions of the same name), rather than from the OS kernel source,
2797 for the same reason -- a user presented with a "bogus foo(bar)" arg
2798 will most likely look at the "foo" man page to see which is the "bar"
2799 arg.
2801 Note that we use our own vki_* types. The one exception is in
2802 PRE_REG_READn calls, where pointer types haven't been changed, because
2803 they don't need to be -- eg. for "foo*" to be used, the type foo need not
2804 be visible.
2806 XXX: some of these are arch-specific, and should be factored out.
2809 #define PRE(name) DEFN_PRE_TEMPLATE(generic, name)
2810 #define POST(name) DEFN_POST_TEMPLATE(generic, name)
2812 PRE(sys_exit)
2814 ThreadState* tst;
2815 /* simple; just make this thread exit */
2816 PRINT("exit( %ld )", SARG1);
2817 PRE_REG_READ1(void, "exit", int, status);
2818 tst = VG_(get_ThreadState)(tid);
2819 /* Set the thread's status to be exiting, then claim that the
2820 syscall succeeded. */
2821 tst->exitreason = VgSrc_ExitThread;
2822 tst->os_state.exitcode = ARG1;
2823 SET_STATUS_Success(0);
2826 PRE(sys_ni_syscall)
2828 PRINT("unimplemented (by the kernel) syscall: %s! (ni_syscall)\n",
2829 VG_SYSNUM_STRING(SYSNO));
2830 PRE_REG_READ0(long, "ni_syscall");
2831 SET_STATUS_Failure( VKI_ENOSYS );
2834 PRE(sys_iopl)
2836 PRINT("sys_iopl ( %" FMT_REGWORD "u )", ARG1);
2837 PRE_REG_READ1(long, "iopl", unsigned long, level);
2840 PRE(sys_fsync)
2842 *flags |= SfMayBlock;
2843 PRINT("sys_fsync ( %" FMT_REGWORD "u )", ARG1);
2844 PRE_REG_READ1(long, "fsync", unsigned int, fd);
2847 PRE(sys_fdatasync)
2849 *flags |= SfMayBlock;
2850 PRINT("sys_fdatasync ( %" FMT_REGWORD "u )", ARG1);
2851 PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
2854 PRE(sys_msync)
2856 *flags |= SfMayBlock;
2857 PRINT("sys_msync ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %#"
2858 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
2859 PRE_REG_READ3(long, "msync",
2860 unsigned long, start, vki_size_t, length, int, flags);
2861 PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
2864 // Nb: getpmsg() and putpmsg() are special additional syscalls used in early
2865 // versions of LiS (Linux Streams). They are not part of the kernel.
2866 // Therefore, we have to provide this type ourself, rather than getting it
2867 // from the kernel sources.
2868 struct vki_pmsg_strbuf {
2869 int maxlen; /* no. of bytes in buffer */
2870 int len; /* no. of bytes returned */
2871 vki_caddr_t buf; /* pointer to data */
2873 PRE(sys_getpmsg)
2875 /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
2876 struct vki_pmsg_strbuf *ctrl;
2877 struct vki_pmsg_strbuf *data;
2878 *flags |= SfMayBlock;
2879 PRINT("sys_getpmsg ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
2880 FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1,
2881 ARG2, ARG3, ARG4, ARG5);
2882 PRE_REG_READ5(int, "getpmsg",
2883 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2884 int *, bandp, int *, flagsp);
2885 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2886 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2887 if (ctrl && ctrl->maxlen > 0)
2888 PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
2889 if (data && data->maxlen > 0)
2890 PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
2891 if (ARG4)
2892 PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
2893 if (ARG5)
2894 PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
2896 POST(sys_getpmsg)
2898 struct vki_pmsg_strbuf *ctrl;
2899 struct vki_pmsg_strbuf *data;
2900 vg_assert(SUCCESS);
2901 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2902 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2903 if (RES == 0 && ctrl && ctrl->len > 0) {
2904 POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
2906 if (RES == 0 && data && data->len > 0) {
2907 POST_MEM_WRITE( (Addr)data->buf, data->len);
2911 PRE(sys_putpmsg)
2913 /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
2914 struct vki_pmsg_strbuf *ctrl;
2915 struct vki_pmsg_strbuf *data;
2916 *flags |= SfMayBlock;
2917 PRINT("sys_putpmsg ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD
2918 "x, %ld, %ld )", SARG1, ARG2, ARG3, SARG4, SARG5);
2919 PRE_REG_READ5(int, "putpmsg",
2920 int, fd, struct strbuf *, ctrl, struct strbuf *, data,
2921 int, band, int, flags);
2922 ctrl = (struct vki_pmsg_strbuf *)(Addr)ARG2;
2923 data = (struct vki_pmsg_strbuf *)(Addr)ARG3;
2924 if (ctrl && ctrl->len > 0)
2925 PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
2926 if (data && data->len > 0)
2927 PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
2930 PRE(sys_getitimer)
2932 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2933 PRINT("sys_getitimer ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
2934 PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
2936 PRE_timeval_WRITE( "getitimer(&value->it_interval)", &(value->it_interval));
2937 PRE_timeval_WRITE( "getitimer(&value->it_value)", &(value->it_value));
2940 POST(sys_getitimer)
2942 if (ARG2 != (Addr)NULL) {
2943 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2944 POST_timeval_WRITE( &(value->it_interval) );
2945 POST_timeval_WRITE( &(value->it_value) );
2949 PRE(sys_setitimer)
2951 PRINT("sys_setitimer ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
2952 SARG1, ARG2, ARG3);
2953 PRE_REG_READ3(long, "setitimer",
2954 int, which,
2955 struct itimerval *, value, struct itimerval *, ovalue);
2956 if (ARG2 != (Addr)NULL) {
2957 struct vki_itimerval *value = (struct vki_itimerval*)(Addr)ARG2;
2958 PRE_timeval_READ( "setitimer(&value->it_interval)",
2959 &(value->it_interval));
2960 PRE_timeval_READ( "setitimer(&value->it_value)",
2961 &(value->it_value));
2963 if (ARG3 != (Addr)NULL) {
2964 struct vki_itimerval *ovalue = (struct vki_itimerval*)(Addr)ARG3;
2965 PRE_timeval_WRITE( "setitimer(&ovalue->it_interval)",
2966 &(ovalue->it_interval));
2967 PRE_timeval_WRITE( "setitimer(&ovalue->it_value)",
2968 &(ovalue->it_value));
2972 POST(sys_setitimer)
2974 if (ARG3 != (Addr)NULL) {
2975 struct vki_itimerval *ovalue = (struct vki_itimerval*)(Addr)ARG3;
2976 POST_timeval_WRITE( &(ovalue->it_interval) );
2977 POST_timeval_WRITE( &(ovalue->it_value) );
2981 PRE(sys_chroot)
2983 PRINT("sys_chroot ( %#" FMT_REGWORD "x )", ARG1);
2984 PRE_REG_READ1(long, "chroot", const char *, path);
2985 PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
2988 PRE(sys_madvise)
2990 *flags |= SfMayBlock;
2991 PRINT("sys_madvise ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )",
2992 ARG1, ARG2, SARG3);
2993 PRE_REG_READ3(long, "madvise",
2994 unsigned long, start, vki_size_t, length, int, advice);
2997 #if HAVE_MREMAP
2998 PRE(sys_mremap)
3000 // Nb: this is different to the glibc version described in the man pages,
3001 // which lacks the fifth 'new_address' argument.
3002 if (ARG4 & VKI_MREMAP_FIXED) {
3003 PRINT("sys_mremap ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
3004 FMT_REGWORD "u, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
3005 ARG1, ARG2, ARG3, ARG4, ARG5);
3006 PRE_REG_READ5(unsigned long, "mremap",
3007 unsigned long, old_addr, unsigned long, old_size,
3008 unsigned long, new_size, unsigned long, flags,
3009 unsigned long, new_addr);
3010 } else {
3011 PRINT("sys_mremap ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
3012 FMT_REGWORD "u, 0x%" FMT_REGWORD "x )",
3013 ARG1, ARG2, ARG3, ARG4);
3014 PRE_REG_READ4(unsigned long, "mremap",
3015 unsigned long, old_addr, unsigned long, old_size,
3016 unsigned long, new_size, unsigned long, flags);
3018 SET_STATUS_from_SysRes(
3019 do_mremap((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid)
3022 #endif /* HAVE_MREMAP */
3024 PRE(sys_nice)
3026 PRINT("sys_nice ( %ld )", SARG1);
3027 PRE_REG_READ1(long, "nice", int, inc);
3030 PRE(sys_mlock2)
3032 *flags |= SfMayBlock;
3033 PRINT("sys_mlock2 ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3034 PRE_REG_READ2(int, "mlock2", void*, addr, vki_size_t, len);
3037 PRE(sys_mlock)
3039 *flags |= SfMayBlock;
3040 PRINT("sys_mlock ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
3041 PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
3044 PRE(sys_munlock)
3046 *flags |= SfMayBlock;
3047 PRINT("sys_munlock ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
3048 PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
3051 PRE(sys_mlockall)
3053 *flags |= SfMayBlock;
3054 PRINT("sys_mlockall ( %" FMT_REGWORD "x )", ARG1);
3055 PRE_REG_READ1(long, "mlockall", int, flags);
3058 PRE(sys_setpriority)
3060 PRINT("sys_setpriority ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
3061 PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
3064 PRE(sys_getpriority)
3066 PRINT("sys_getpriority ( %ld, %ld )", SARG1, SARG2);
3067 PRE_REG_READ2(long, "getpriority", int, which, int, who);
3070 #if !defined(VGO_freebsd)
3071 PRE(sys_pwrite64)
3073 *flags |= SfMayBlock;
3074 #if VG_WORDSIZE == 4
3075 PRINT("sys_pwrite64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3076 FMT_REGWORD "u, %lld )", ARG1, ARG2, ARG3, (Long)MERGE64(ARG4,ARG5));
3077 PRE_REG_READ5(ssize_t, "pwrite64",
3078 unsigned int, fd, const char *, buf, vki_size_t, count,
3079 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
3080 #elif VG_WORDSIZE == 8
3081 PRINT("sys_pwrite64 ( %lu, %#lx, %lu, %ld )",
3082 ARG1, ARG2, ARG3, SARG4);
3083 PRE_REG_READ4(ssize_t, "pwrite64",
3084 unsigned int, fd, const char *, buf, vki_size_t, count,
3085 Word, offset);
3086 #else
3087 # error Unexpected word size
3088 #endif
3089 PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
3091 #endif
3093 PRE(sys_sync)
3095 *flags |= SfMayBlock;
3096 PRINT("sys_sync ( )");
3097 PRE_REG_READ0(long, "sync");
3100 #if !defined(VGP_nanomips_linux)
3101 PRE(sys_fstatfs)
3103 FUSE_COMPATIBLE_MAY_BLOCK();
3104 PRINT("sys_fstatfs ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3105 PRE_REG_READ2(long, "fstatfs",
3106 unsigned int, fd, struct statfs *, buf);
3107 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
3110 POST(sys_fstatfs)
3112 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
3115 PRE(sys_fstatfs64)
3117 FUSE_COMPATIBLE_MAY_BLOCK();
3118 PRINT("sys_fstatfs64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#"
3119 FMT_REGWORD "x )", ARG1, ARG2, ARG3);
3120 PRE_REG_READ3(long, "fstatfs64",
3121 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
3122 PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
3124 POST(sys_fstatfs64)
3126 POST_MEM_WRITE( ARG3, ARG2 );
3128 #endif
3130 PRE(sys_getsid)
3132 PRINT("sys_getsid ( %ld )", SARG1);
3133 PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
3136 #if !defined(VGO_freebsd)
3137 PRE(sys_pread64)
3139 *flags |= SfMayBlock;
3140 #if VG_WORDSIZE == 4
3141 PRINT("sys_pread64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3142 FMT_REGWORD "u, %lld )", ARG1, ARG2, ARG3, (Long)MERGE64(ARG4,ARG5));
3143 PRE_REG_READ5(ssize_t, "pread64",
3144 unsigned int, fd, char *, buf, vki_size_t, count,
3145 vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset));
3146 #elif VG_WORDSIZE == 8
3147 PRINT("sys_pread64 ( %lu, %#lx, %lu, %ld )",
3148 ARG1, ARG2, ARG3, SARG4);
3149 PRE_REG_READ4(ssize_t, "pread64",
3150 unsigned int, fd, char *, buf, vki_size_t, count,
3151 Word, offset);
3152 #else
3153 # error Unexpected word size
3154 #endif
3155 PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
3157 POST(sys_pread64)
3159 vg_assert(SUCCESS);
3160 if (RES > 0) {
3161 POST_MEM_WRITE( ARG2, RES );
3164 #endif
3166 PRE(sys_mknod)
3168 FUSE_COMPATIBLE_MAY_BLOCK();
3169 PRINT("sys_mknod ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#"
3170 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, ARG2, ARG3 );
3171 PRE_REG_READ3(long, "mknod",
3172 const char *, pathname, int, mode, unsigned, dev);
3173 PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
3176 PRE(sys_flock)
3178 *flags |= SfMayBlock;
3179 PRINT("sys_flock ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2 );
3180 PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
3183 // Pre_read a char** argument.
3184 void ML_(pre_argv_envp)(Addr a, ThreadId tid, const HChar *s1, const HChar *s2)
3186 while (True) {
3187 Addr a_deref;
3188 Addr* a_p = (Addr*)a;
3189 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
3190 a_deref = *a_p;
3191 if (0 == a_deref)
3192 break;
3193 PRE_MEM_RASCIIZ( s2, a_deref );
3194 a += sizeof(char*);
3198 static Bool i_am_the_only_thread ( void )
3200 Int c = VG_(count_living_threads)();
3201 vg_assert(c >= 1); /* stay sane */
3202 return c == 1;
3205 /* Wait until all other threads disappear. */
3206 void VG_(reap_threads)(ThreadId self)
3208 while (!i_am_the_only_thread()) {
3209 /* Let other thread(s) run */
3210 VG_(vg_yield)();
3211 VG_(poll_signals)(self);
3213 vg_assert(i_am_the_only_thread());
3216 /* This handles the common part of the PRE macro for execve and execveat. */
3217 void handle_pre_sys_execve(ThreadId tid, SyscallStatus *status, Addr pathname,
3218 Addr arg_2, Addr arg_3, ExecveType execveType,
3219 Bool check_pathptr)
3221 HChar* path = NULL; /* path to executable */
3222 HChar** envp = NULL;
3223 HChar** argv = NULL;
3224 HChar** arg2copy;
3225 HChar* launcher_basename = NULL;
3226 ThreadState* tst;
3227 Int i, j, tot_args;
3228 SysRes res;
3229 Bool setuid_allowed, trace_this_child;
3230 const char *str;
3231 char str2[30], str3[30];
3232 Addr arg_2_check = arg_2;
3234 switch (execveType) {
3235 case EXECVE:
3236 str = "execve";
3237 break;
3238 case EXECVEAT:
3239 str = "execveat";
3240 break;
3241 case FEXECVE:
3242 str = "fexecve";
3243 break;
3244 default:
3245 vg_assert(False);
3248 VG_(strcpy)(str2, str);
3249 VG_(strcpy)(str3, str);
3251 VG_(strcat)(str2, "(argv)");
3252 VG_(strcat)(str3, "(argv[0])");
3254 /* argv[] should not be NULL and valid. */
3255 PRE_MEM_READ(str2, arg_2_check, sizeof(Addr));
3257 /* argv[0] should not be NULL and valid. */
3258 if (ML_(safe_to_deref)((HChar **) (Addr)arg_2_check, sizeof(HChar *))) {
3259 Addr argv0 = *(Addr*)arg_2_check;
3260 PRE_MEM_RASCIIZ( str3, argv0 );
3261 /* The rest of argv can be NULL or a valid string pointer. */
3262 if (VG_(am_is_valid_for_client)(arg_2_check, sizeof(HChar), VKI_PROT_READ)) {
3263 arg_2_check += sizeof(HChar*);
3264 str3[VG_(strlen)(str)] = '\0';
3265 VG_(strcat)(str3, "(argv[i])");
3266 ML_(pre_argv_envp)( arg_2_check, tid, str2, str3 );
3268 } else {
3269 SET_STATUS_Failure(VKI_EFAULT);
3270 return;
3272 // Reset helper strings to syscall name.
3273 str2[VG_(strlen)(str)] = '\0';
3274 str3[VG_(strlen)(str)] = '\0';
3275 if (arg_3 != 0) {
3276 /* At least the terminating NULL must be addressable. */
3277 if (!ML_(safe_to_deref)((HChar **) (Addr)arg_3, sizeof(HChar *))) {
3278 SET_STATUS_Failure(VKI_EFAULT);
3279 return;
3281 VG_(strcat)(str2, "(envp)");
3282 VG_(strcat)(str3, "(envp[i])");
3283 ML_(pre_argv_envp)( arg_3, tid, str2, str3 );
3286 vg_assert(VG_(is_valid_tid)(tid));
3287 tst = VG_(get_ThreadState)(tid);
3289 /* Erk. If the exec fails, then the following will have made a
3290 mess of things which makes it hard for us to continue. The
3291 right thing to do is piece everything together again in
3292 POST(execve), but that's close to impossible. Instead, we make
3293 an effort to check that the execve will work before actually
3294 doing it. */
3296 /* Check that the name at least begins in client-accessible storage.
3297 If we didn't create it ourselves in execveat. */
3298 if (check_pathptr
3299 && !VG_(am_is_valid_for_client)( pathname, 1, VKI_PROT_READ )) {
3300 SET_STATUS_Failure( VKI_EFAULT );
3301 return;
3304 // debug-only printing
3305 if (0) {
3306 VG_(printf)("pathname = %p(%s)\n", (void*)(Addr)pathname, (HChar*)(Addr)pathname);
3307 if (arg_2) {
3308 VG_(printf)("arg_2 = ");
3309 Int q;
3310 HChar** vec = (HChar**)(Addr)arg_2;
3311 for (q = 0; vec[q]; q++)
3312 VG_(printf)("%p(%s) ", vec[q], vec[q]);
3313 VG_(printf)("\n");
3314 } else {
3315 VG_(printf)("arg_2 = null\n");
3319 // Decide whether or not we want to follow along
3320 { // Make 'child_argv' be a pointer to the child's arg vector
3321 // (skipping the exe name)
3322 const HChar** child_argv = (const HChar**)(Addr)arg_2;
3323 if (child_argv && child_argv[0] == NULL)
3324 child_argv = NULL;
3325 trace_this_child = VG_(should_we_trace_this_child)( (HChar*)(Addr)pathname,
3326 child_argv );
3329 // Do the important checks: it is a file, is executable, permissions are
3330 // ok, etc. We allow setuid executables to run only in the case when
3331 // we are not simulating them, that is, they to be run natively.
3332 setuid_allowed = trace_this_child ? False : True;
3333 res = VG_(pre_exec_check)((const HChar *)(Addr)pathname, NULL, setuid_allowed);
3334 if (sr_isError(res)) {
3335 SET_STATUS_Failure( sr_Err(res) );
3336 return;
3339 /* If we're tracing the child, and the launcher name looks bogus
3340 (possibly because launcher.c couldn't figure it out, see
3341 comments therein) then we have no option but to fail. */
3342 if (trace_this_child
3343 && (VG_(name_of_launcher) == NULL
3344 || VG_(name_of_launcher)[0] != '/')) {
3345 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
3346 return;
3349 /* After this point, we can't recover if the execve fails. */
3350 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)(Addr)pathname);
3353 // Terminate gdbserver if it is active.
3354 if (VG_(clo_vgdb) != Vg_VgdbNo) {
3355 // If the child will not be traced, we need to terminate gdbserver
3356 // to cleanup the gdbserver resources (e.g. the FIFO files).
3357 // If child will be traced, we also terminate gdbserver: the new
3358 // Valgrind will start a fresh gdbserver after exec.
3359 VG_(gdbserver) (0);
3362 /* Resistance is futile. Nuke all other threads. POSIX mandates
3363 this. (Really, nuke them all, since the new process will make
3364 its own new thread.) */
3365 VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
3366 VG_(reap_threads)(tid);
3368 // Set up the child's exe path.
3370 if (trace_this_child) {
3372 // We want to exec the launcher. Get its pre-remembered path.
3373 path = VG_(name_of_launcher);
3374 // VG_(name_of_launcher) should have been acquired by m_main at
3375 // startup.
3376 vg_assert(path);
3378 launcher_basename = VG_(strrchr)(path, '/');
3379 if (launcher_basename == NULL || launcher_basename[1] == 0) {
3380 launcher_basename = path; // hmm, tres dubious
3381 } else {
3382 launcher_basename++;
3385 } else {
3386 path = (HChar*)(Addr)pathname;
3389 // Set up the child's environment.
3391 // Remove the valgrind-specific stuff from the environment so the
3392 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
3393 // This is done unconditionally, since if we are tracing the child,
3394 // the child valgrind will set up the appropriate client environment.
3395 // Nb: we make a copy of the environment before trying to mangle it
3396 // as it might be in read-only memory (this was bug #101881).
3398 // Then, if tracing the child, set VALGRIND_LIB for it.
3400 if (arg_3 == 0) {
3401 envp = NULL;
3402 } else {
3403 envp = VG_(env_clone)( (HChar**)(Addr)arg_3 );
3404 if (envp == NULL) goto hosed;
3405 VG_(env_remove_valgrind_env_stuff)( envp, True /*ro_strings*/, NULL );
3408 if (trace_this_child) {
3409 // Set VALGRIND_LIB in arg_3 (the environment)
3410 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
3413 // Set up the child's args. If not tracing it, they are
3414 // simply arg_2. Otherwise, they are
3416 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [pathname] ++ arg_2[1..]
3418 // except that the first VG_(args_for_valgrind_noexecpass) args
3419 // are omitted.
3421 if (!trace_this_child) {
3422 argv = (HChar**)(Addr)arg_2;
3423 } else {
3424 vg_assert( VG_(args_for_valgrind) );
3425 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
3426 vg_assert( VG_(args_for_valgrind_noexecpass)
3427 <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
3428 /* how many args in total will there be? */
3429 // launcher basename
3430 tot_args = 1;
3431 // V's args
3432 tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
3433 tot_args -= VG_(args_for_valgrind_noexecpass);
3434 // name of client exe
3435 tot_args++;
3436 // args for client exe, skipping [0]
3437 arg2copy = (HChar**)(Addr)arg_2;
3438 if (arg2copy && arg2copy[0]) {
3439 for (i = 1; arg2copy[i]; i++)
3440 tot_args++;
3442 // allocate
3443 argv = VG_(malloc)( "di.syswrap.pre_sys_execve.1",
3444 (tot_args+1) * sizeof(HChar*) );
3445 // copy
3446 j = 0;
3447 argv[j++] = launcher_basename;
3448 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
3449 if (i < VG_(args_for_valgrind_noexecpass))
3450 continue;
3451 argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
3453 argv[j++] = (HChar*)(Addr)pathname;
3454 if (arg2copy && arg2copy[0])
3455 for (i = 1; arg2copy[i]; i++)
3456 argv[j++] = arg2copy[i];
3457 argv[j++] = NULL;
3458 // check
3459 vg_assert(j == tot_args+1);
3463 Set the signal state up for exec.
3465 We need to set the real signal state to make sure the exec'd
3466 process gets SIG_IGN properly.
3468 Also set our real sigmask to match the client's sigmask so that
3469 the exec'd child will get the right mask. First we need to
3470 clear out any pending signals so they they don't get delivered,
3471 which would confuse things.
3473 XXX This is a bug - the signals should remain pending, and be
3474 delivered to the new process after exec. There's also a
3475 race-condition, since if someone delivers us a signal between
3476 the sigprocmask and the execve, we'll still get the signal. Oh
3477 well.
3480 vki_sigset_t allsigs;
3481 vki_siginfo_t info;
3483 /* What this loop does: it queries SCSS (the signal state that
3484 the client _thinks_ the kernel is in) by calling
3485 VG_(do_sys_sigaction), and modifies the real kernel signal
3486 state accordingly. */
3487 for (i = 1; i < VG_(max_signal); i++) {
3488 vki_sigaction_fromK_t sa_f;
3489 vki_sigaction_toK_t sa_t;
3490 VG_(do_sys_sigaction)(i, NULL, &sa_f);
3491 VG_(convert_sigaction_fromK_to_toK)(&sa_f, &sa_t);
3492 if (sa_t.ksa_handler == VKI_SIG_IGN)
3493 VG_(sigaction)(i, &sa_t, NULL);
3494 else {
3495 sa_t.ksa_handler = VKI_SIG_DFL;
3496 VG_(sigaction)(i, &sa_t, NULL);
3500 VG_(sigfillset)(&allsigs);
3501 while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
3504 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
3507 if (0) {
3508 HChar **cpp;
3509 VG_(printf)("exec: %s\n", path);
3510 for (cpp = argv; cpp && *cpp; cpp++)
3511 VG_(printf)("argv: %s\n", *cpp);
3512 if (0)
3513 for (cpp = envp; cpp && *cpp; cpp++)
3514 VG_(printf)("env: %s\n", *cpp);
3517 // always execute this because it's executing valgrind, not the "target" exe
3518 SET_STATUS_from_SysRes(
3519 VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp));
3521 /* If we got here, then the execve failed. We've already made way
3522 too much of a mess to continue, so we have to abort. */
3523 hosed:
3524 vg_assert(FAILURE);
3525 VG_(message)(Vg_UserMsg, "execve(%#" FMT_REGWORD "x(%s), %#" FMT_REGWORD
3526 "x, %#" FMT_REGWORD "x) failed, errno %lu\n",
3527 pathname, (HChar*)(Addr)pathname, arg_2, arg_3, ERR);
3528 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
3529 "execve() failing, so I'm dying.\n");
3530 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
3531 "or work out how to recover.\n");
3532 VG_(exit)(101);
3536 // XXX: prototype here seemingly doesn't match the prototype for i386-linux,
3537 // but it seems to work nonetheless...
3538 PRE(sys_execve)
3540 PRINT("sys_execve ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %#"
3541 FMT_REGWORD "x )", ARG1, (HChar*)(Addr)ARG1, ARG2, ARG3);
3542 PRE_REG_READ3(vki_off_t, "execve",
3543 char *, filename, char **, argv, char **, envp);
3544 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
3546 char *pathname = (char *)ARG1;
3547 Addr arg_2 = (Addr)ARG2;
3548 Addr arg_3 = (Addr)ARG3;
3550 handle_pre_sys_execve(tid, status, (Addr)pathname, arg_2, arg_3, EXECVE, True);
3553 PRE(sys_access)
3555 FUSE_COMPATIBLE_MAY_BLOCK();
3556 PRINT("sys_access ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
3557 (HChar*)(Addr)ARG1, SARG2);
3558 PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
3559 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
3562 PRE(sys_alarm)
3564 PRINT("sys_alarm ( %" FMT_REGWORD "u )", ARG1);
3565 PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
3568 PRE(sys_brk)
3570 Addr brk_limit = VG_(brk_limit);
3571 Addr brk_new;
3573 /* libc says: int brk(void *end_data_segment);
3574 kernel says: void* brk(void* end_data_segment); (more or less)
3576 libc returns 0 on success, and -1 (and sets errno) on failure.
3577 Nb: if you ask to shrink the dataseg end below what it
3578 currently is, that always succeeds, even if the dataseg end
3579 doesn't actually change (eg. brk(0)). Unless it seg faults.
3581 Kernel returns the new dataseg end. If the brk() failed, this
3582 will be unchanged from the old one. That's why calling (kernel)
3583 brk(0) gives the current dataseg end (libc brk() just returns
3584 zero in that case).
3586 Both will seg fault if you shrink it back into a text segment.
3588 PRINT("sys_brk ( %#" FMT_REGWORD "x )", ARG1);
3589 PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
3591 brk_new = do_brk(ARG1, tid);
3592 SET_STATUS_Success( brk_new );
3594 if (brk_new == ARG1) {
3595 /* brk() succeeded */
3596 if (brk_new < brk_limit) {
3597 /* successfully shrunk the data segment. */
3598 VG_TRACK( die_mem_brk, (Addr)ARG1,
3599 brk_limit-ARG1 );
3600 } else
3601 if (brk_new > brk_limit) {
3602 /* successfully grew the data segment */
3603 VG_TRACK( new_mem_brk, brk_limit,
3604 ARG1-brk_limit, tid );
3606 } else {
3607 /* brk() failed */
3608 vg_assert(brk_limit == brk_new);
3612 PRE(sys_chdir)
3614 FUSE_COMPATIBLE_MAY_BLOCK();
3615 PRINT("sys_chdir ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
3616 PRE_REG_READ1(long, "chdir", const char *, path);
3617 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
3620 PRE(sys_chmod)
3622 FUSE_COMPATIBLE_MAY_BLOCK();
3623 PRINT("sys_chmod ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,
3624 (HChar*)(Addr)ARG1, ARG2);
3625 PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
3626 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
3629 PRE(sys_chown)
3631 FUSE_COMPATIBLE_MAY_BLOCK();
3632 PRINT("sys_chown ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
3633 FMT_REGWORD "x )", ARG1,(char*)(Addr)ARG1,ARG2,ARG3);
3634 PRE_REG_READ3(long, "chown",
3635 const char *, path, vki_uid_t, owner, vki_gid_t, group);
3636 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
3639 PRE(sys_lchown)
3641 FUSE_COMPATIBLE_MAY_BLOCK();
3642 PRINT("sys_lchown ( %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%"
3643 FMT_REGWORD "x )", ARG1,(char*)(Addr)ARG1,ARG2,ARG3);
3644 PRE_REG_READ3(long, "lchown",
3645 const char *, path, vki_uid_t, owner, vki_gid_t, group);
3646 PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
3649 PRE(sys_close)
3651 FUSE_COMPATIBLE_MAY_BLOCK();
3652 PRINT("sys_close ( %" FMT_REGWORD "u )", ARG1);
3653 PRE_REG_READ1(long, "close", unsigned int, fd);
3655 /* Detect and negate attempts by the client to close Valgrind's log fd */
3656 if ( (!ML_(fd_allowed)(ARG1, "close", tid, False))
3657 /* If doing -d style logging (which is to fd=2), don't
3658 allow that to be closed either. */
3659 || (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0) )
3660 SET_STATUS_Failure( VKI_EBADF );
3661 else {
3662 /* We used to do close tracking in the POST handler, but that is
3663 only called on success. Even if the close syscall fails the
3664 file descriptor is still really closed/invalid. So we do the
3665 recording and checking here. */
3666 if (VG_(clo_track_fds)) ML_(record_fd_close)(tid, ARG1);
3670 PRE(sys_dup)
3672 PRINT("sys_dup ( %" FMT_REGWORD "u )", ARG1);
3673 PRE_REG_READ1(long, "dup", unsigned int, oldfd);
3676 POST(sys_dup)
3678 vg_assert(SUCCESS);
3679 if (!ML_(fd_allowed)(RES, "dup", tid, True)) {
3680 VG_(close)(RES);
3681 SET_STATUS_Failure( VKI_EMFILE );
3682 } else {
3683 if (VG_(clo_track_fds))
3684 ML_(record_fd_open_named)(tid, RES);
3688 PRE(sys_dup2)
3690 PRINT("sys_dup2 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3691 PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
3692 if (!ML_(fd_allowed)(ARG2, "dup2", tid, True))
3693 SET_STATUS_Failure( VKI_EBADF );
3696 POST(sys_dup2)
3698 vg_assert(SUCCESS);
3699 if (VG_(clo_track_fds))
3700 ML_(record_fd_open_named)(tid, RES);
3703 PRE(sys_fchdir)
3705 FUSE_COMPATIBLE_MAY_BLOCK();
3706 PRINT("sys_fchdir ( %" FMT_REGWORD "u )", ARG1);
3707 PRE_REG_READ1(long, "fchdir", unsigned int, fd);
3710 PRE(sys_fchown)
3712 FUSE_COMPATIBLE_MAY_BLOCK();
3713 PRINT("sys_fchown ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %"
3714 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
3715 PRE_REG_READ3(long, "fchown",
3716 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
3719 PRE(sys_fchmod)
3721 FUSE_COMPATIBLE_MAY_BLOCK();
3722 PRINT("sys_fchmod ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3723 PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
3726 #if !defined(VGP_nanomips_linux) && !defined (VGO_freebsd)
3727 PRE(sys_newfstat)
3729 FUSE_COMPATIBLE_MAY_BLOCK();
3730 PRINT("sys_newfstat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
3731 PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
3732 PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
3735 POST(sys_newfstat)
3737 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
3739 #endif
3741 #if !defined(VGO_solaris) && !defined(VGP_arm64_linux) && \
3742 !defined(VGP_nanomips_linux)
3743 static vki_sigset_t fork_saved_mask;
3745 // In Linux, the sys_fork() function varies across architectures, but we
3746 // ignore the various args it gets, and so it looks arch-neutral. Hmm.
3747 PRE(sys_fork)
3749 Bool is_child;
3750 Int child_pid;
3751 vki_sigset_t mask;
3753 PRINT("sys_fork ( )");
3754 PRE_REG_READ0(long, "fork");
3756 /* Block all signals during fork, so that we can fix things up in
3757 the child without being interrupted. */
3758 VG_(sigfillset)(&mask);
3759 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
3761 VG_(do_atfork_pre)(tid);
3763 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
3765 if (!SUCCESS) return;
3767 #if defined(VGO_linux) || defined(VGO_freebsd)
3768 // RES is 0 for child, non-0 (the child's PID) for parent.
3769 is_child = ( RES == 0 ? True : False );
3770 child_pid = ( is_child ? -1 : RES );
3771 #elif defined(VGO_darwin)
3772 // RES is the child's pid. RESHI is 1 for child, 0 for parent.
3773 is_child = RESHI;
3774 child_pid = RES;
3775 #else
3776 # error Unknown OS
3777 #endif
3779 if (is_child) {
3780 VG_(do_atfork_child)(tid);
3782 /* restore signal mask */
3783 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
3784 } else {
3785 VG_(do_atfork_parent)(tid);
3787 PRINT(" fork: process %d created child %d\n", VG_(getpid)(), child_pid);
3789 /* restore signal mask */
3790 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
3793 #endif // !defined(VGO_solaris) && !defined(VGP_arm64_linux)
3795 PRE(sys_ftruncate)
3797 *flags |= SfMayBlock;
3798 PRINT("sys_ftruncate ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
3799 PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
3802 PRE(sys_truncate)
3804 *flags |= SfMayBlock;
3805 PRINT("sys_truncate ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
3806 ARG1, (HChar*)(Addr)ARG1, ARG2);
3807 PRE_REG_READ2(long, "truncate",
3808 const char *, path, unsigned long, length);
3809 PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
3812 PRE(sys_ftruncate64)
3814 *flags |= SfMayBlock;
3815 #if VG_WORDSIZE == 4
3816 PRINT("sys_ftruncate64 ( %" FMT_REGWORD "u, %llu )", ARG1,
3817 MERGE64(ARG2,ARG3));
3818 PRE_REG_READ3(long, "ftruncate64",
3819 unsigned int, fd,
3820 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
3821 #else
3822 PRINT("sys_ftruncate64 ( %lu, %lu )", ARG1, ARG2);
3823 PRE_REG_READ2(long, "ftruncate64",
3824 unsigned int,fd, UWord,length);
3825 #endif
3828 PRE(sys_truncate64)
3830 *flags |= SfMayBlock;
3831 #if VG_WORDSIZE == 4
3832 PRINT("sys_truncate64 ( %#" FMT_REGWORD "x, %lld )", ARG1,
3833 (Long)MERGE64(ARG2, ARG3));
3834 PRE_REG_READ3(long, "truncate64",
3835 const char *, path,
3836 UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length));
3837 #else
3838 PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)ARG2);
3839 PRE_REG_READ2(long, "truncate64",
3840 const char *,path, UWord,length);
3841 #endif
3842 PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
3845 PRE(sys_getdents)
3847 *flags |= SfMayBlock;
3848 PRINT("sys_getdents ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %" FMT_REGWORD
3849 "u )", ARG1, ARG2, ARG3);
3850 PRE_REG_READ3(long, "getdents",
3851 unsigned int, fd, struct vki_dirent *, dirp,
3852 unsigned int, count);
3853 PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
3856 POST(sys_getdents)
3858 vg_assert(SUCCESS);
3859 if (RES > 0)
3860 POST_MEM_WRITE( ARG2, RES );
3863 PRE(sys_getdents64)
3865 *flags |= SfMayBlock;
3866 PRINT("sys_getdents64 ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
3867 FMT_REGWORD "u )",ARG1, ARG2, ARG3);
3868 PRE_REG_READ3(long, "getdents64",
3869 unsigned int, fd, struct vki_dirent64 *, dirp,
3870 unsigned int, count);
3871 PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 );
3874 POST(sys_getdents64)
3876 vg_assert(SUCCESS);
3877 if (RES > 0)
3878 POST_MEM_WRITE( ARG2, RES );
3881 PRE(sys_getgroups)
3883 PRINT("sys_getgroups ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
3884 PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
3885 if (ARG1 > 0)
3886 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
3889 POST(sys_getgroups)
3891 vg_assert(SUCCESS);
3892 if (ARG1 > 0 && RES > 0)
3893 POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
3896 PRE(sys_getcwd)
3898 // Comment from linux/fs/dcache.c:
3899 // NOTE! The user-level library version returns a character pointer.
3900 // The kernel system call just returns the length of the buffer filled
3901 // (which includes the ending '\0' character), or a negative error
3902 // value.
3903 // Is this Linux-specific? If so it should be moved to syswrap-linux.c.
3904 PRINT("sys_getcwd ( %#" FMT_REGWORD "x, %llu )", ARG1,(ULong)ARG2);
3905 PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size);
3906 PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 );
3909 POST(sys_getcwd)
3911 vg_assert(SUCCESS);
3912 if (RES != (Addr)NULL)
3913 POST_MEM_WRITE( ARG1, RES );
3916 PRE(sys_geteuid)
3918 PRINT("sys_geteuid ( )");
3919 PRE_REG_READ0(long, "geteuid");
3922 PRE(sys_getegid)
3924 PRINT("sys_getegid ( )");
3925 PRE_REG_READ0(long, "getegid");
3928 PRE(sys_getgid)
3930 PRINT("sys_getgid ( )");
3931 PRE_REG_READ0(long, "getgid");
3934 PRE(sys_getpid)
3936 PRINT("sys_getpid ()");
3937 PRE_REG_READ0(long, "getpid");
3940 PRE(sys_getpgid)
3942 PRINT("sys_getpgid ( %ld )", SARG1);
3943 PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
3946 PRE(sys_getpgrp)
3948 PRINT("sys_getpgrp ()");
3949 PRE_REG_READ0(long, "getpgrp");
3952 PRE(sys_getppid)
3954 PRINT("sys_getppid ()");
3955 PRE_REG_READ0(long, "getppid");
3958 static void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2)
3960 POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) );
3962 #ifdef _RLIMIT_POSIX_FLAG
3963 // Darwin will sometimes set _RLIMIT_POSIX_FLAG on getrlimit calls.
3964 // Unset it here to make the switch case below work correctly.
3965 a1 &= ~_RLIMIT_POSIX_FLAG;
3966 #endif
3968 switch (a1) {
3969 case VKI_RLIMIT_NOFILE:
3970 ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit);
3971 ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit);
3972 break;
3974 case VKI_RLIMIT_DATA:
3975 *((struct vki_rlimit *)a2) = VG_(client_rlimit_data);
3976 break;
3978 case VKI_RLIMIT_STACK:
3979 *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack);
3980 break;
3984 PRE(sys_old_getrlimit)
3986 PRINT("sys_old_getrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )",
3987 ARG1, ARG2);
3988 PRE_REG_READ2(long, "old_getrlimit",
3989 unsigned int, resource, struct rlimit *, rlim);
3990 PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
3993 POST(sys_old_getrlimit)
3995 common_post_getrlimit(tid, ARG1, ARG2);
3998 PRE(sys_getrlimit)
4000 PRINT("sys_getrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
4001 PRE_REG_READ2(long, "getrlimit",
4002 unsigned int, resource, struct rlimit *, rlim);
4003 PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
4006 POST(sys_getrlimit)
4008 common_post_getrlimit(tid, ARG1, ARG2);
4011 PRE(sys_getrusage)
4013 PRINT("sys_getrusage ( %ld, %#" FMT_REGWORD "x )", SARG1, ARG2);
4014 PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
4015 PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
4018 POST(sys_getrusage)
4020 vg_assert(SUCCESS);
4021 if (RES == 0)
4022 POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
4025 PRE(sys_gettimeofday)
4027 PRINT("sys_gettimeofday ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4028 ARG1,ARG2);
4029 PRE_REG_READ2(long, "gettimeofday",
4030 struct timeval *, tv, struct timezone *, tz);
4031 // GrP fixme does darwin write to *tz anymore?
4032 if (ARG1 != 0)
4033 PRE_timeval_WRITE( "gettimeofday(tv)", (Addr)ARG1 );
4034 if (ARG2 != 0)
4035 PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
4038 POST(sys_gettimeofday)
4040 vg_assert(SUCCESS);
4041 if (RES == 0) {
4042 if (ARG1 != 0)
4043 POST_timeval_WRITE( (Addr)ARG1 );
4044 if (ARG2 != 0)
4045 POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) );
4049 PRE(sys_settimeofday)
4051 PRINT("sys_settimeofday ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",
4052 ARG1,ARG2);
4053 PRE_REG_READ2(long, "settimeofday",
4054 struct timeval *, tv, struct timezone *, tz);
4055 if (ARG1 != 0)
4056 PRE_timeval_READ( "settimeofday(tv)", (Addr)ARG1 );
4057 if (ARG2 != 0) {
4058 PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
4059 /* maybe should warn if tz->tz_dsttime is non-zero? */
4063 PRE(sys_getuid)
4065 PRINT("sys_getuid ( )");
4066 PRE_REG_READ0(long, "getuid");
4069 void ML_(PRE_unknown_ioctl)(ThreadId tid, UWord request, UWord arg)
4071 /* We don't have any specific information on it, so
4072 try to do something reasonable based on direction and
4073 size bits. The encoding scheme is described in
4074 /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h .
4076 According to Simon Hausmann, _IOC_READ means the kernel
4077 writes a value to the ioctl value passed from the user
4078 space and the other way around with _IOC_WRITE. */
4080 #if defined(VGO_solaris)
4081 /* Majority of Solaris ioctl requests does not honour direction hints. */
4082 UInt dir = _VKI_IOC_NONE;
4083 #else
4084 UInt dir = _VKI_IOC_DIR(request);
4085 #endif
4086 UInt size = _VKI_IOC_SIZE(request);
4088 if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) {
4090 * Be very lax about ioctl handling; the only
4091 * assumption is that the size is correct. Doesn't
4092 * require the full buffer to be initialized when
4093 * writing. Without this, using some device
4094 * drivers with a large number of strange ioctl
4095 * commands becomes very tiresome.
4097 } else if (dir == _VKI_IOC_NONE && size > 0) {
4098 static UWord unknown_ioctl[10];
4099 static Int moans = sizeof(unknown_ioctl) / sizeof(unknown_ioctl[0]);
4101 if (moans > 0 && !VG_(clo_xml)) {
4102 /* Check if have not already moaned for this request. */
4103 UInt i;
4104 for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) {
4105 if (unknown_ioctl[i] == request)
4106 break;
4107 if (unknown_ioctl[i] == 0) {
4108 unknown_ioctl[i] = request;
4109 moans--;
4110 VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx"
4111 " with no direction hints.\n", request);
4112 VG_(umsg)(" This could cause spurious value errors to appear.\n");
4113 VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for "
4114 "guidance on writing a proper wrapper.\n" );
4115 //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
4116 return;
4120 } else {
4121 //VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request);
4122 //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
4123 if ((dir & _VKI_IOC_WRITE) && size > 0)
4124 PRE_MEM_READ( "ioctl(generic)", arg, size);
4125 if ((dir & _VKI_IOC_READ) && size > 0)
4126 PRE_MEM_WRITE( "ioctl(generic)", arg, size);
4130 void ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg)
4132 /* We don't have any specific information on it, so
4133 try to do something reasonable based on direction and
4134 size bits. The encoding scheme is described in
4135 /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h .
4137 According to Simon Hausmann, _IOC_READ means the kernel
4138 writes a value to the ioctl value passed from the user
4139 space and the other way around with _IOC_WRITE. */
4141 UInt dir = _VKI_IOC_DIR(request);
4142 UInt size = _VKI_IOC_SIZE(request);
4143 if (size > 0 && (dir & _VKI_IOC_READ)
4144 && res == 0
4145 && arg != (Addr)NULL) {
4146 POST_MEM_WRITE(arg, size);
4151 If we're sending a SIGKILL to one of our own threads, then simulate
4152 it rather than really sending the signal, so that the target thread
4153 gets a chance to clean up. Returns True if we did the killing (or
4154 no killing is necessary), and False if the caller should use the
4155 normal kill syscall.
4157 "pid" is any pid argument which can be passed to kill; group kills
4158 (< -1, 0), and owner kills (-1) are ignored, on the grounds that
4159 they'll most likely hit all the threads and we won't need to worry
4160 about cleanup. In truth, we can't fully emulate these multicast
4161 kills.
4163 "tgid" is a thread group id. If it is not -1, then the target
4164 thread must be in that thread group.
4166 Bool ML_(do_sigkill)(Int pid, Int tgid)
4168 ThreadState *tst;
4169 ThreadId tid;
4171 if (pid <= 0)
4172 return False;
4174 tid = VG_(lwpid_to_vgtid)(pid);
4175 if (tid == VG_INVALID_THREADID)
4176 return False; /* none of our threads */
4178 tst = VG_(get_ThreadState)(tid);
4179 if (tst == NULL || tst->status == VgTs_Empty)
4180 return False; /* hm, shouldn't happen */
4182 if (tgid != -1 && tst->os_state.threadgroup != tgid)
4183 return False; /* not the right thread group */
4185 /* Fatal SIGKILL sent to one of our threads.
4186 "Handle" the signal ourselves, as trying to have tid
4187 handling the signal causes termination problems (see #409367
4188 and #409141).
4189 Moreover, as a process cannot do anything when receiving SIGKILL,
4190 it is not particularly crucial that "tid" does the work to
4191 terminate the process. */
4193 if (VG_(clo_trace_signals))
4194 VG_(message)(Vg_DebugMsg,
4195 "Thread %u %s being killed with SIGKILL, running tid: %u\n",
4196 tst->tid, VG_(name_of_ThreadStatus) (tst->status), VG_(running_tid));
4198 if (!VG_(is_running_thread)(tid))
4199 tst = VG_(get_ThreadState)(VG_(running_tid));
4200 VG_(nuke_all_threads_except) (VG_(running_tid), VgSrc_FatalSig);
4201 VG_(reap_threads)(VG_(running_tid));
4202 tst->exitreason = VgSrc_FatalSig;
4203 tst->os_state.fatalsig = VKI_SIGKILL;
4205 return True;
4208 PRE(sys_kill)
4210 PRINT("sys_kill ( %ld, %ld )", SARG1, SARG2);
4211 PRE_REG_READ2(long, "kill", int, pid, int, signal);
4212 if (!ML_(client_signal_OK)(ARG2)) {
4213 SET_STATUS_Failure( VKI_EINVAL );
4214 return;
4217 /* If we're sending SIGKILL, check to see if the target is one of
4218 our threads and handle it specially. */
4219 if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1))
4220 SET_STATUS_Success(0);
4221 else
4222 /* re syscall3: Darwin has a 3rd arg, which is a flag (boolean)
4223 affecting how posix-compliant the call is. I guess it is
4224 harmless to pass the 3rd arg on other platforms; hence pass
4225 it on all. */
4226 SET_STATUS_from_SysRes( VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3) );
4228 if (VG_(clo_trace_signals))
4229 VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld\n",
4230 SARG2, SARG1);
4232 /* This kill might have given us a pending signal. Ask for a check once
4233 the syscall is done. */
4234 *flags |= SfPollAfter;
4237 PRE(sys_link)
4239 *flags |= SfMayBlock;
4240 PRINT("sys_link ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )", ARG1,
4241 (char*)(Addr)ARG1,ARG2,(char*)(Addr)ARG2);
4242 PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
4243 PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
4244 PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
4247 #if !defined(VGP_nanomips_linux) && !defined(VGO_freebsd)
4248 PRE(sys_newlstat)
4250 PRINT("sys_newlstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,
4251 (char*)(Addr)ARG1,ARG2);
4252 PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
4253 PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
4254 PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
4257 POST(sys_newlstat)
4259 vg_assert(SUCCESS);
4260 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4262 #endif
4264 PRE(sys_mkdir)
4266 *flags |= SfMayBlock;
4267 PRINT("sys_mkdir ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
4268 (HChar*)(Addr)ARG1, SARG2);
4269 PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
4270 PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
4273 PRE(sys_mprotect)
4275 PRINT("sys_mprotect ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %"
4276 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4277 PRE_REG_READ3(long, "mprotect",
4278 unsigned long, addr, vki_size_t, len, unsigned long, prot);
4280 Addr addr = ARG1;
4281 SizeT len = ARG2;
4282 Int prot = ARG3;
4284 handle_sys_mprotect (tid, status, &addr, &len, &prot);
4286 ARG1 = addr;
4287 ARG2 = len;
4288 ARG3 = prot;
4290 /* This will be called from the generic mprotect, or the linux specific
4291 pkey_mprotect. Pass pointers to ARG1, ARG2 and ARG3 as addr, len and prot,
4292 they might be adjusted and have to assigned back to ARG1, ARG2 and ARG3. */
4293 void handle_sys_mprotect(ThreadId tid, SyscallStatus* status,
4294 Addr *addr, SizeT *len, Int *prot)
4296 if (!ML_(valid_client_addr)(*addr, *len, tid, "mprotect")) {
4297 #if defined(VGO_freebsd)
4298 SET_STATUS_Failure( VKI_EINVAL );
4299 #else
4300 SET_STATUS_Failure( VKI_ENOMEM );
4301 #endif
4303 #if defined(VKI_PROT_GROWSDOWN)
4304 else
4305 if (*prot & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) {
4306 /* Deal with mprotects on growable stack areas.
4308 The critical files to understand all this are mm/mprotect.c
4309 in the kernel and sysdeps/unix/sysv/linux/dl-execstack.c in
4310 glibc.
4312 The kernel provides PROT_GROWSDOWN and PROT_GROWSUP which
4313 round the start/end address of mprotect to the start/end of
4314 the underlying vma and glibc uses that as an easy way to
4315 change the protection of the stack by calling mprotect on the
4316 last page of the stack with PROT_GROWSDOWN set.
4318 The sanity check provided by the kernel is that the vma must
4319 have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate. */
4320 UInt grows = *prot & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP);
4321 NSegment const *aseg = VG_(am_find_nsegment)(*addr);
4322 NSegment const *rseg;
4324 vg_assert(aseg);
4326 if (grows == VKI_PROT_GROWSDOWN) {
4327 rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ );
4328 if (rseg
4329 && rseg->kind == SkResvn
4330 && rseg->smode == SmUpper
4331 && rseg->end+1 == aseg->start) {
4332 Addr end = *addr + *len;
4333 *addr = aseg->start;
4334 *len = end - aseg->start;
4335 *prot &= ~VKI_PROT_GROWSDOWN;
4336 } else {
4337 SET_STATUS_Failure( VKI_EINVAL );
4339 } else if (grows == VKI_PROT_GROWSUP) {
4340 rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ );
4341 if (rseg
4342 && rseg->kind == SkResvn
4343 && rseg->smode == SmLower
4344 && aseg->end+1 == rseg->start) {
4345 *len = aseg->end - *addr + 1;
4346 *prot &= ~VKI_PROT_GROWSUP;
4347 } else {
4348 SET_STATUS_Failure( VKI_EINVAL );
4350 } else {
4351 /* both GROWSUP and GROWSDOWN */
4352 SET_STATUS_Failure( VKI_EINVAL );
4355 #endif // defined(VKI_PROT_GROWSDOWN)
4358 POST(sys_mprotect)
4360 Addr a = ARG1;
4361 SizeT len = ARG2;
4362 Int prot = ARG3;
4364 ML_(notify_core_and_tool_of_mprotect)(a, len, prot);
4367 PRE(sys_munmap)
4369 if (0) VG_(printf)(" munmap( %#" FMT_REGWORD "x )\n", ARG1);
4370 PRINT("sys_munmap ( %#" FMT_REGWORD "x, %llu )", ARG1,(ULong)ARG2);
4371 PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
4373 if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
4374 SET_STATUS_Failure( VKI_EINVAL );
4377 POST(sys_munmap)
4379 Addr a = ARG1;
4380 SizeT len = ARG2;
4382 ML_(notify_core_and_tool_of_munmap)( a, len );
4385 PRE(sys_mincore)
4387 PRINT("sys_mincore ( %#" FMT_REGWORD "x, %llu, %#" FMT_REGWORD "x )",
4388 ARG1, (ULong)ARG2, ARG3);
4389 PRE_REG_READ3(long, "mincore",
4390 unsigned long, start, vki_size_t, length,
4391 unsigned char *, vec);
4392 PRE_MEM_WRITE( "mincore(vec)", ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
4394 POST(sys_mincore)
4396 POST_MEM_WRITE( ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE );
4399 PRE(sys_nanosleep)
4401 *flags |= SfMayBlock|SfPostOnFail;
4402 PRINT("sys_nanosleep ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )", ARG1,ARG2);
4403 PRE_REG_READ2(long, "nanosleep",
4404 struct timespec *, req, struct timespec *, rem);
4405 PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) );
4406 if (ARG2 != 0)
4407 PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) );
4410 POST(sys_nanosleep)
4412 vg_assert(SUCCESS || FAILURE);
4413 if (ARG2 != 0 && FAILURE && ERR == VKI_EINTR)
4414 POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
4417 #if defined(VGO_linux) || defined(VGO_solaris)
4418 /* Handles the case where the open is of /proc/self/auxv or
4419 /proc/<pid>/auxv, and just gives out a copy of the fd for the
4420 fake file we cooked up at startup (in m_main). Also, seeks the
4421 cloned fd back to the start.
4422 Returns True if auxv open was handled (status is set). */
4423 Bool ML_(handle_auxv_open)(SyscallStatus *status, const HChar *filename,
4424 int flags)
4426 HChar name[30]; // large enough
4428 if (!ML_(safe_to_deref)((const void *) filename, 1))
4429 return False;
4431 /* Opening /proc/<pid>/auxv or /proc/self/auxv? */
4432 VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)());
4433 if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/auxv"))
4434 return False;
4436 /* Allow to open the file only for reading. */
4437 if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
4438 SET_STATUS_Failure(VKI_EACCES);
4439 return True;
4442 # if defined(VGO_solaris)
4443 VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_auxv_fd));
4444 SysRes sres = VG_(open)(name, flags, 0);
4445 SET_STATUS_from_SysRes(sres);
4446 # else
4447 SysRes sres = VG_(dup)(VG_(cl_auxv_fd));
4448 SET_STATUS_from_SysRes(sres);
4449 if (!sr_isError(sres)) {
4450 OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
4451 if (off < 0)
4452 SET_STATUS_Failure(VKI_EMFILE);
4454 # endif
4456 return True;
4458 #endif // defined(VGO_linux) || defined(VGO_solaris)
4460 #if defined(VGO_linux)
4461 Bool ML_(handle_self_exe_open)(SyscallStatus *status, const HChar *filename,
4462 int flags)
4464 HChar name[30]; // large enough for /proc/<int>/exe
4466 if (!ML_(safe_to_deref)((const void *) filename, 1))
4467 return False;
4469 /* Opening /proc/<pid>/exe or /proc/self/exe? */
4470 VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
4471 if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/exe"))
4472 return False;
4474 /* Allow to open the file only for reading. */
4475 if (flags & (VKI_O_WRONLY | VKI_O_RDWR)) {
4476 SET_STATUS_Failure(VKI_EACCES);
4477 return True;
4480 SysRes sres = VG_(dup)(VG_(cl_exec_fd));
4481 SET_STATUS_from_SysRes(sres);
4482 if (!sr_isError(sres)) {
4483 OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
4484 if (off < 0)
4485 SET_STATUS_Failure(VKI_EMFILE);
4488 return True;
4490 #endif // defined(VGO_linux)
4492 PRE(sys_open)
4494 if (ARG2 & VKI_O_CREAT) {
4495 // 3-arg version
4496 PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld, %ld )",ARG1,
4497 (HChar*)(Addr)ARG1, SARG2, SARG3);
4498 PRE_REG_READ3(long, "open",
4499 const char *, filename, int, flags, int, mode);
4500 } else {
4501 // 2-arg version
4502 PRINT("sys_open ( %#" FMT_REGWORD "x(%s), %ld )",ARG1,
4503 (HChar*)(Addr)ARG1, SARG2);
4504 PRE_REG_READ2(long, "open",
4505 const char *, filename, int, flags);
4507 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
4509 #if defined(VGO_linux)
4510 /* Handle the case where the open is of /proc/self/cmdline or
4511 /proc/<pid>/cmdline, and just give it a copy of the fd for the
4512 fake file we cooked up at startup (in m_main). Also, seek the
4513 cloned fd back to the start. */
4515 HChar name[30]; // large enough
4516 HChar* arg1s = (HChar*) (Addr)ARG1;
4517 SysRes sres;
4519 VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
4520 if (ML_(safe_to_deref)( arg1s, 1 )
4521 && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/cmdline"))) {
4522 sres = VG_(dup)( VG_(cl_cmdline_fd) );
4523 SET_STATUS_from_SysRes( sres );
4524 if (!sr_isError(sres)) {
4525 OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET );
4526 if (off < 0)
4527 SET_STATUS_Failure( VKI_EMFILE );
4529 return;
4533 /* Handle also the case of /proc/self/auxv or /proc/<pid>/auxv
4534 or /proc/self/exe or /proc/<pid>/exe. */
4535 if (ML_(handle_auxv_open)(status, (const HChar *)(Addr)ARG1, ARG2)
4536 || ML_(handle_self_exe_open)(status, (const HChar *)(Addr)ARG1, ARG2))
4537 return;
4538 #endif // defined(VGO_linux)
4540 /* Otherwise handle normally */
4541 *flags |= SfMayBlock;
4544 POST(sys_open)
4546 vg_assert(SUCCESS);
4547 if (!ML_(fd_allowed)(RES, "open", tid, True)) {
4548 VG_(close)(RES);
4549 SET_STATUS_Failure( VKI_EMFILE );
4550 } else {
4551 if (VG_(clo_track_fds))
4552 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
4556 PRE(sys_read)
4558 *flags |= SfMayBlock;
4559 PRINT("sys_read ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4560 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4561 PRE_REG_READ3(ssize_t, "read",
4562 int, fd, char *, buf, vki_size_t, count);
4564 if (!ML_(fd_allowed)(ARG1, "read", tid, False))
4565 SET_STATUS_Failure( VKI_EBADF );
4566 else
4567 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
4570 POST(sys_read)
4572 vg_assert(SUCCESS);
4573 POST_MEM_WRITE( ARG2, RES );
4576 PRE(sys_write)
4578 Bool ok;
4579 *flags |= SfMayBlock;
4580 PRINT("sys_write ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4581 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4582 PRE_REG_READ3(ssize_t, "write",
4583 unsigned int, fd, const char *, buf, vki_size_t, count);
4584 /* check to see if it is allowed. If not, try for an exemption from
4585 --sim-hints=enable-outer (used for self hosting). */
4586 ok = ML_(fd_allowed)(ARG1, "write", tid, False);
4587 if (!ok && ARG1 == 2/*stderr*/
4588 && SimHintiS(SimHint_enable_outer, VG_(clo_sim_hints)))
4589 ok = True;
4590 #if defined(VGO_solaris)
4591 if (!ok && VG_(vfork_fildes_addr) != NULL
4592 && *VG_(vfork_fildes_addr) >= 0 && *VG_(vfork_fildes_addr) == ARG1)
4593 ok = True;
4594 #endif
4595 if (!ok)
4596 SET_STATUS_Failure( VKI_EBADF );
4597 else
4598 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
4601 PRE(sys_creat)
4603 *flags |= SfMayBlock;
4604 PRINT("sys_creat ( %#" FMT_REGWORD "x(%s), %ld )", ARG1,
4605 (HChar*)(Addr)ARG1, SARG2);
4606 PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
4607 PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
4610 POST(sys_creat)
4612 vg_assert(SUCCESS);
4613 if (!ML_(fd_allowed)(RES, "creat", tid, True)) {
4614 VG_(close)(RES);
4615 SET_STATUS_Failure( VKI_EMFILE );
4616 } else {
4617 if (VG_(clo_track_fds))
4618 ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)(Addr)ARG1);
4622 PRE(sys_poll)
4624 /* struct pollfd {
4625 int fd; -- file descriptor
4626 short events; -- requested events
4627 short revents; -- returned events
4629 int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
4631 UInt i;
4632 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
4633 *flags |= SfMayBlock;
4634 PRINT("sys_poll ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %ld )\n",
4635 ARG1, ARG2, SARG3);
4636 PRE_REG_READ3(long, "poll",
4637 struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout);
4639 for (i = 0; i < ARG2; i++) {
4640 PRE_MEM_READ( "poll(ufds.fd)",
4641 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
4642 if (ML_(safe_to_deref)(&ufds[i].fd, sizeof(ufds[i].fd)) && ufds[i].fd >= 0) {
4643 PRE_MEM_READ( "poll(ufds.events)",
4644 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
4646 PRE_MEM_WRITE( "poll(ufds.revents)",
4647 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
4651 POST(sys_poll)
4653 if (SUCCESS) {
4654 UInt i;
4655 struct vki_pollfd* ufds = (struct vki_pollfd *)(Addr)ARG1;
4656 for (i = 0; i < ARG2; i++)
4657 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
4661 PRE(sys_readlink)
4663 FUSE_COMPATIBLE_MAY_BLOCK();
4664 PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )",
4665 ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3);
4666 PRE_REG_READ3(long, "readlink",
4667 const char *, path, char *, buf, int, bufsiz);
4668 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
4669 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
4672 POST(sys_readlink)
4674 #if defined(VGO_linux) || defined(VGO_solaris)
4676 Word saved = SYSNO;
4677 #if defined(VGO_linux)
4678 #define PID_EXEPATH "/proc/%d/exe"
4679 #define SELF_EXEPATH "/proc/self/exe"
4680 #define SELF_EXEFD "/proc/self/fd/%d"
4681 #elif defined(VGO_solaris)
4682 #define PID_EXEPATH "/proc/%d/path/a.out"
4683 #define SELF_EXEPATH "/proc/self/path/a.out"
4684 #define SELF_EXEFD "/proc/self/path/%d"
4685 #endif
4687 * Handle the case where readlink is looking at /proc/self/exe or
4688 * /proc/<pid>/exe, or equivalent on Solaris.
4690 HChar name[30]; // large enough
4691 HChar* arg1s = (HChar*) (Addr)ARG1;
4692 VG_(sprintf)(name, PID_EXEPATH, VG_(getpid)());
4693 if (ML_(safe_to_deref)(arg1s, 1)
4694 && (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, SELF_EXEPATH))) {
4695 VG_(sprintf)(name, SELF_EXEFD, VG_(cl_exec_fd));
4696 SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name,
4697 ARG2, ARG3));
4700 #endif
4701 if (SUCCESS && RES > 0)
4702 POST_MEM_WRITE( ARG2, RES );
4705 PRE(sys_readv)
4707 Int i;
4708 struct vki_iovec * vec;
4709 char buf[sizeof("readv(vector[])") + 11];
4710 *flags |= SfMayBlock;
4711 PRINT("sys_readv ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
4712 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
4713 PRE_REG_READ3(ssize_t, "readv",
4714 unsigned long, fd, const struct iovec *, vector,
4715 unsigned long, count);
4716 if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
4717 SET_STATUS_Failure( VKI_EBADF );
4718 } else {
4719 if ((Int)ARG3 >= 0)
4720 PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
4722 if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) {
4723 vec = (struct vki_iovec *)(Addr)ARG2;
4724 for (i = 0; i < (Int)ARG3; i++) {
4725 VG_(sprintf)(buf, "readv(vector[%d])", i);
4726 PRE_MEM_WRITE(buf, (Addr)vec[i].iov_base, vec[i].iov_len );
4732 POST(sys_readv)
4734 vg_assert(SUCCESS);
4735 if (RES > 0) {
4736 Int i;
4737 struct vki_iovec * vec = (struct vki_iovec *)(Addr)ARG2;
4738 Int remains = RES;
4740 /* RES holds the number of bytes read. */
4741 for (i = 0; i < (Int)ARG3; i++) {
4742 Int nReadThisBuf = vec[i].iov_len;
4743 if (nReadThisBuf > remains) nReadThisBuf = remains;
4744 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
4745 remains -= nReadThisBuf;
4746 if (remains < 0) VG_(core_panic)("readv: remains < 0");
4751 PRE(sys_rename)
4753 FUSE_COMPATIBLE_MAY_BLOCK();
4754 PRINT("sys_rename ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )", ARG1,
4755 (char*)(Addr)ARG1,ARG2,(char*)(Addr)ARG2);
4756 PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
4757 PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 );
4758 PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
4761 PRE(sys_rmdir)
4763 *flags |= SfMayBlock;
4764 PRINT("sys_rmdir ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
4765 PRE_REG_READ1(long, "rmdir", const char *, pathname);
4766 PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
4769 PRE(sys_select)
4771 *flags |= SfMayBlock;
4772 PRINT("sys_select ( %ld, %#" FMT_REGWORD "x, %#" FMT_REGWORD "x, %#"
4773 FMT_REGWORD "x, %#" FMT_REGWORD "x )", SARG1, ARG2, ARG3, ARG4, ARG5);
4774 PRE_REG_READ5(long, "select",
4775 int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
4776 vki_fd_set *, exceptfds, struct vki_timeval *, timeout);
4777 // XXX: this possibly understates how much memory is read.
4778 if (ARG2 != 0)
4779 PRE_MEM_READ( "select(readfds)",
4780 ARG2, ARG1/8 /* __FD_SETSIZE/8 */ );
4781 if (ARG3 != 0)
4782 PRE_MEM_READ( "select(writefds)",
4783 ARG3, ARG1/8 /* __FD_SETSIZE/8 */ );
4784 if (ARG4 != 0)
4785 PRE_MEM_READ( "select(exceptfds)",
4786 ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
4787 if (ARG5 != 0)
4788 PRE_timeval_READ( "select(timeout)", (Addr)ARG5 );
4791 PRE(sys_setgid)
4793 PRINT("sys_setgid ( %" FMT_REGWORD "u )", ARG1);
4794 PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
4797 PRE(sys_setsid)
4799 PRINT("sys_setsid ( )");
4800 PRE_REG_READ0(long, "setsid");
4803 PRE(sys_setgroups)
4805 PRINT("setgroups ( %llu, %#" FMT_REGWORD "x )", (ULong)ARG1, ARG2);
4806 PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
4807 if (ARG1 > 0)
4808 PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
4811 PRE(sys_setpgid)
4813 PRINT("setpgid ( %ld, %ld )", SARG1, SARG2);
4814 PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
4817 PRE(sys_setregid)
4819 PRINT("sys_setregid ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
4820 PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
4823 PRE(sys_setreuid)
4825 PRINT("sys_setreuid ( 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )",
4826 ARG1, ARG2);
4827 PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
4830 PRE(sys_setrlimit)
4832 UWord arg1 = ARG1;
4833 PRINT("sys_setrlimit ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2);
4834 PRE_REG_READ2(long, "setrlimit",
4835 unsigned int, resource, struct rlimit *, rlim);
4836 PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
4838 #ifdef _RLIMIT_POSIX_FLAG
4839 // Darwin will sometimes set _RLIMIT_POSIX_FLAG on setrlimit calls.
4840 // Unset it here to make the if statements below work correctly.
4841 arg1 &= ~_RLIMIT_POSIX_FLAG;
4842 #endif
4844 if (!VG_(am_is_valid_for_client)(ARG2, sizeof(struct vki_rlimit),
4845 VKI_PROT_READ)) {
4846 SET_STATUS_Failure( VKI_EFAULT );
4848 else if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4849 > ((struct vki_rlimit *)(Addr)ARG2)->rlim_max) {
4850 #if defined(VGO_freebsd)
4851 SET_STATUS_Failure( VKI_EPERM );
4852 #else
4853 SET_STATUS_Failure( VKI_EINVAL );
4854 #endif
4856 else if (arg1 == VKI_RLIMIT_NOFILE) {
4857 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
4858 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max != VG_(fd_hard_limit)) {
4859 SET_STATUS_Failure( VKI_EPERM );
4861 else {
4862 VG_(fd_soft_limit) = ((struct vki_rlimit *)(Addr)ARG2)->rlim_cur;
4863 SET_STATUS_Success( 0 );
4866 else if (arg1 == VKI_RLIMIT_DATA) {
4867 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4868 > VG_(client_rlimit_data).rlim_max ||
4869 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max
4870 > VG_(client_rlimit_data).rlim_max) {
4871 SET_STATUS_Failure( VKI_EPERM );
4873 else {
4874 VG_(client_rlimit_data) = *(struct vki_rlimit *)(Addr)ARG2;
4875 SET_STATUS_Success( 0 );
4878 else if (arg1 == VKI_RLIMIT_STACK && tid == 1) {
4879 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur
4880 > VG_(client_rlimit_stack).rlim_max ||
4881 ((struct vki_rlimit *)(Addr)ARG2)->rlim_max
4882 > VG_(client_rlimit_stack).rlim_max) {
4883 SET_STATUS_Failure( VKI_EPERM );
4885 else {
4886 /* Change the value of client_stack_szB to the rlim_cur value but
4887 only if it is smaller than the size of the allocated stack for the
4888 client.
4889 TODO: All platforms should set VG_(clstk_max_size) as part of their
4890 setup_client_stack(). */
4891 if ((VG_(clstk_max_size) == 0)
4892 || (((struct vki_rlimit *) (Addr)ARG2)->rlim_cur <= VG_(clstk_max_size)))
4893 VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)(Addr)ARG2)->rlim_cur;
4895 VG_(client_rlimit_stack) = *(struct vki_rlimit *)(Addr)ARG2;
4896 SET_STATUS_Success( 0 );
4901 PRE(sys_setuid)
4903 PRINT("sys_setuid ( %" FMT_REGWORD "u )", ARG1);
4904 PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
4907 #if !defined(VGP_nanomips_linux) && !defined(VGO_freebsd)
4908 PRE(sys_newstat)
4910 FUSE_COMPATIBLE_MAY_BLOCK();
4911 PRINT("sys_newstat ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4912 ARG1,(char*)(Addr)ARG1,ARG2);
4913 PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
4914 PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
4915 PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
4918 POST(sys_newstat)
4920 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
4922 #endif
4924 #if !defined(VGP_nanomips_linux)
4925 PRE(sys_statfs)
4927 FUSE_COMPATIBLE_MAY_BLOCK();
4928 PRINT("sys_statfs ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
4929 ARG1, (char*)(Addr)ARG1, ARG2);
4930 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
4931 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
4932 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
4934 POST(sys_statfs)
4936 POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
4939 PRE(sys_statfs64)
4941 FUSE_COMPATIBLE_MAY_BLOCK();
4942 PRINT("sys_statfs64 ( %#" FMT_REGWORD "x(%s), %llu, %#" FMT_REGWORD "x )",
4943 ARG1, (char*)(Addr)ARG1, (ULong)ARG2, ARG3);
4944 PRE_REG_READ3(long, "statfs64",
4945 const char *, path, vki_size_t, size, struct statfs64 *, buf);
4946 PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
4947 PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
4949 POST(sys_statfs64)
4951 POST_MEM_WRITE( ARG3, ARG2 );
4953 #endif
4955 PRE(sys_symlink)
4957 *flags |= SfMayBlock;
4958 PRINT("sys_symlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x(%s) )",
4959 ARG1, (char*)(Addr)ARG1, ARG2, (char*)(Addr)ARG2);
4960 PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
4961 PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
4962 PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
4965 PRE(sys_time)
4967 /* time_t time(time_t *t); */
4968 PRINT("sys_time ( %#" FMT_REGWORD "x )",ARG1);
4969 PRE_REG_READ1(long, "time", int *, t);
4970 if (ARG1 != 0) {
4971 PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) );
4975 POST(sys_time)
4977 if (ARG1 != 0) {
4978 POST_MEM_WRITE( ARG1, sizeof(vki_time_t) );
4982 PRE(sys_times)
4984 PRINT("sys_times ( %#" FMT_REGWORD "x )", ARG1);
4985 PRE_REG_READ1(long, "times", struct tms *, buf);
4986 if (ARG1 != 0) {
4987 PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
4991 POST(sys_times)
4993 if (ARG1 != 0) {
4994 POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
4998 PRE(sys_umask)
5000 PRINT("sys_umask ( %ld )", SARG1);
5001 PRE_REG_READ1(long, "umask", int, mask);
5004 PRE(sys_unlink)
5006 *flags |= SfMayBlock;
5007 PRINT("sys_unlink ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
5008 PRE_REG_READ1(long, "unlink", const char *, pathname);
5009 PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
5012 #if !defined(VGO_freebsd)
5013 PRE(sys_newuname)
5015 PRINT("sys_newuname ( %#" FMT_REGWORD "x )", ARG1);
5016 PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
5017 PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) );
5020 POST(sys_newuname)
5022 if (ARG1 != 0) {
5023 POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) );
5026 #endif
5028 PRE(sys_waitpid)
5030 *flags |= SfMayBlock;
5031 PRINT("sys_waitpid ( %ld, %#" FMT_REGWORD "x, %ld )", SARG1, ARG2, SARG3);
5032 PRE_REG_READ3(long, "waitpid",
5033 vki_pid_t, pid, unsigned int *, status, int, options);
5035 if (ARG2 != (Addr)NULL)
5036 PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) );
5039 POST(sys_waitpid)
5041 if (ARG2 != (Addr)NULL)
5042 POST_MEM_WRITE( ARG2, sizeof(int) );
5045 PRE(sys_wait4)
5047 *flags |= SfMayBlock;
5048 PRINT("sys_wait4 ( %ld, %#" FMT_REGWORD "x, %ld, %#" FMT_REGWORD "x )",
5049 SARG1, ARG2, SARG3, ARG4);
5051 PRE_REG_READ4(long, "wait4",
5052 vki_pid_t, pid, unsigned int *, status, int, options,
5053 struct rusage *, rusage);
5054 if (ARG2 != (Addr)NULL)
5055 PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) );
5056 if (ARG4 != (Addr)NULL)
5057 PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) );
5060 POST(sys_wait4)
5062 if (ARG2 != (Addr)NULL)
5063 POST_MEM_WRITE( ARG2, sizeof(int) );
5064 if (ARG4 != (Addr)NULL)
5065 POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
5068 PRE(sys_writev)
5070 Int i;
5071 struct vki_iovec * vec;
5072 char buf[sizeof("writev(vector[])") + 11];
5073 *flags |= SfMayBlock;
5074 PRINT("sys_writev ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x, %"
5075 FMT_REGWORD "u )", ARG1, ARG2, ARG3);
5076 PRE_REG_READ3(ssize_t, "writev",
5077 unsigned long, fd, const struct iovec *, vector,
5078 unsigned long, count);
5079 if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) {
5080 SET_STATUS_Failure( VKI_EBADF );
5081 } else {
5082 if ((Int)ARG3 >= 0)
5083 PRE_MEM_READ( "writev(vector)",
5084 ARG2, ARG3 * sizeof(struct vki_iovec) );
5086 if (ML_(safe_to_deref)((const void*)ARG2, ARG3*sizeof(struct vki_iovec *))) {
5087 vec = (struct vki_iovec *)(Addr)ARG2;
5088 for (i = 0; i < (Int)ARG3; i++) {
5089 VG_(sprintf)(buf, "writev(vector[%d])", i);
5090 PRE_MEM_READ( buf, (Addr)vec[i].iov_base, vec[i].iov_len );
5096 PRE(sys_utimes)
5098 FUSE_COMPATIBLE_MAY_BLOCK();
5099 PRINT("sys_utimes ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )",
5100 ARG1, (char*)(Addr)ARG1, ARG2);
5101 PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
5102 PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
5103 if (ARG2 != 0) {
5104 PRE_timeval_READ( "utimes(tvp[0])", (Addr)ARG2 );
5105 PRE_timeval_READ( "utimes(tvp[1])",
5106 (Addr)ARG2+sizeof(struct vki_timeval) );
5110 PRE(sys_acct)
5112 PRINT("sys_acct ( %#" FMT_REGWORD "x(%s) )", ARG1,(char*)(Addr)ARG1);
5113 PRE_REG_READ1(long, "acct", const char *, filename);
5114 PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
5117 PRE(sys_pause)
5119 *flags |= SfMayBlock;
5120 PRINT("sys_pause ( )");
5121 PRE_REG_READ0(long, "pause");
5124 PRE(sys_sigaltstack)
5126 PRINT("sigaltstack ( %#" FMT_REGWORD "x, %#" FMT_REGWORD "x )",ARG1,ARG2);
5127 PRE_REG_READ2(int, "sigaltstack",
5128 const vki_stack_t *, ss, vki_stack_t *, oss);
5129 if (ARG1 != 0) {
5130 const vki_stack_t *ss = (vki_stack_t *)(Addr)ARG1;
5131 PRE_MEM_READ( "sigaltstack(ss->ss_sp)", (Addr)&ss->ss_sp, sizeof(ss->ss_sp) );
5132 PRE_MEM_READ( "sigaltstack(ss->ss_size)", (Addr)&ss->ss_size, sizeof(ss->ss_size) );
5133 PRE_MEM_READ( "sigaltstack(ss->ss_flags)", (Addr)&ss->ss_flags, sizeof(ss->ss_flags) );
5135 if (ARG2 != 0) {
5136 PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
5139 /* Be safe. */
5140 if (ARG1 && !ML_(safe_to_deref((void*)(Addr)ARG1, sizeof(vki_stack_t)))) {
5141 SET_STATUS_Failure(VKI_EFAULT);
5142 return;
5144 if (ARG2 && !ML_(safe_to_deref((void*)(Addr)ARG2, sizeof(vki_stack_t)))) {
5145 SET_STATUS_Failure(VKI_EFAULT);
5146 return;
5149 SET_STATUS_from_SysRes(
5150 VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)(Addr)ARG1,
5151 (vki_stack_t*)(Addr)ARG2)
5154 POST(sys_sigaltstack)
5156 vg_assert(SUCCESS);
5157 if (RES == 0 && ARG2 != 0)
5158 POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
5161 PRE(sys_sethostname)
5163 PRINT("sys_sethostname ( %#" FMT_REGWORD "x, %ld )", ARG1, SARG2);
5164 PRE_REG_READ2(long, "sethostname", char *, name, int, len);
5165 PRE_MEM_READ( "sethostname(name)", ARG1, ARG2 );
5168 #undef PRE
5169 #undef POST
5171 #endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
5173 /*--------------------------------------------------------------------*/
5174 /*--- end ---*/
5175 /*--------------------------------------------------------------------*/