195f1037b50883fa81420116d7a694be0099ab015florian/* -*- mode: C; c-basic-offset: 3; -*- */ 2de4a1d01951937632098a6cda45859afa587a06fsewardj 3de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 46e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj/*--- Wrappers for generic Unix system calls ---*/ 58b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- syswrap-generic.c ---*/ 6de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 7de4a1d01951937632098a6cda45859afa587a06fsewardj 8de4a1d01951937632098a6cda45859afa587a06fsewardj/* 9b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn This file is part of Valgrind, a dynamic binary instrumentation 10b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn framework. 11de4a1d01951937632098a6cda45859afa587a06fsewardj 120f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj Copyright (C) 2000-2013 Julian Seward 13de4a1d01951937632098a6cda45859afa587a06fsewardj jseward@acm.org 14de4a1d01951937632098a6cda45859afa587a06fsewardj 15de4a1d01951937632098a6cda45859afa587a06fsewardj This program is free software; you can redistribute it and/or 16de4a1d01951937632098a6cda45859afa587a06fsewardj modify it under the terms of the GNU General Public License as 17de4a1d01951937632098a6cda45859afa587a06fsewardj published by the Free Software Foundation; either version 2 of the 18de4a1d01951937632098a6cda45859afa587a06fsewardj License, or (at your option) any later version. 19de4a1d01951937632098a6cda45859afa587a06fsewardj 20de4a1d01951937632098a6cda45859afa587a06fsewardj This program is distributed in the hope that it will be useful, but 21de4a1d01951937632098a6cda45859afa587a06fsewardj WITHOUT ANY WARRANTY; without even the implied warranty of 22de4a1d01951937632098a6cda45859afa587a06fsewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23de4a1d01951937632098a6cda45859afa587a06fsewardj General Public License for more details. 24de4a1d01951937632098a6cda45859afa587a06fsewardj 25de4a1d01951937632098a6cda45859afa587a06fsewardj You should have received a copy of the GNU General Public License 26de4a1d01951937632098a6cda45859afa587a06fsewardj along with this program; if not, write to the Free Software 27de4a1d01951937632098a6cda45859afa587a06fsewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28de4a1d01951937632098a6cda45859afa587a06fsewardj 02111-1307, USA. 29de4a1d01951937632098a6cda45859afa587a06fsewardj 30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn The GNU General Public License is contained in the file COPYING. 31de4a1d01951937632098a6cda45859afa587a06fsewardj*/ 32de4a1d01951937632098a6cda45859afa587a06fsewardj 338b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGO_linux) || defined(VGO_darwin) 348b68b64759254d514d98328c496cbd88cde4c9a5njn 35c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h" 364cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h" 374cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vkiscnums.h" 38c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_threadstate.h" 3945f4e7c91119c7d01a59f5e827c67841632c9314sewardj#include "pub_core_debuginfo.h" // VG_(di_notify_*) 4055f9d1a56f3542c68f5b24006c14b1f9aaefff6fsewardj#include "pub_core_aspacemgr.h" 4145f4e7c91119c7d01a59f5e827c67841632c9314sewardj#include "pub_core_transtab.h" // VG_(discard_translations) 4214c7cc5a5fbe9526329f058116f921988efe679esewardj#include "pub_core_xarray.h" 4345f4e7c91119c7d01a59f5e827c67841632c9314sewardj#include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit) 44899ce73b9eb1f679562e93f8e5c162aa049413f1njn#include "pub_core_debuglog.h" 450087c501c6356fb083c0ea12d87263aca7abf25anjn#include "pub_core_errormgr.h" 46c91f58449e6fc2a4ce0851639a342c4277612fbbflorian#include "pub_core_gdbserver.h" // VG_(gdbserver) 4797405b2d134b52880d6dbec3eb2929e2002c2542njn#include "pub_core_libcbase.h" 48a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj#include "pub_core_libcassert.h" 49de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn#include "pub_core_libcfile.h" 50de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn#include "pub_core_libcprint.h" 51f39e9a36dca9642668a66c6b054f81c88650bcb9njn#include "pub_core_libcproc.h" 52de62cbf607eb0e2dccb8bd6c7caf34180f528badnjn#include "pub_core_libcsignal.h" 53f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_machine.h" // VG_(get_SP) 54af1d7dfc9412c09d24ea10118f3fd1082f92e49dnjn#include "pub_core_mallocfree.h" 55a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj#include "pub_core_options.h" 56c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_scheduler.h" 57a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj#include "pub_core_signals.h" 58419bbcb905b239dc209da742f976f1c45abf16d0njn#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)() 599abd608244d8123868d027f616fa928156615d5anjn#include "pub_core_syscall.h" 60c1b0181cbd6f296401daa6ff0e6e14d3a8ab91a0njn#include "pub_core_syswrap.h" 61419bbcb905b239dc209da742f976f1c45abf16d0njn#include "pub_core_tooliface.h" 627375061f0ecd9534a27ade9bb4fbe47ddce41298njn#include "pub_core_ume.h" 6338a74d2cc4670e3eb559adff51a376cd6ec98005philippe#include "pub_core_stacks.h" 64855d93d2e9940890b28874520fa4c1677bf825e2jsgf 65a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj#include "priv_types_n_macros.h" 66c1b0181cbd6f296401daa6ff0e6e14d3a8ab91a0njn#include "priv_syswrap-generic.h" 67855d93d2e9940890b28874520fa4c1677bf825e2jsgf 68870f7451dcc5ff1ec6c84e8bb2832bd5834459c2bart#include "config.h" 69870f7451dcc5ff1ec6c84e8bb2832bd5834459c2bart 70855d93d2e9940890b28874520fa4c1677bf825e2jsgf 7138a74d2cc4670e3eb559adff51a376cd6ec98005philippevoid ML_(guess_and_register_stack) (Addr sp, ThreadState* tst) 7238a74d2cc4670e3eb559adff51a376cd6ec98005philippe{ 7338a74d2cc4670e3eb559adff51a376cd6ec98005philippe Bool debug = False; 7438a74d2cc4670e3eb559adff51a376cd6ec98005philippe NSegment const* seg; 7538a74d2cc4670e3eb559adff51a376cd6ec98005philippe 7638a74d2cc4670e3eb559adff51a376cd6ec98005philippe /* We don't really know where the client stack is, because its 7738a74d2cc4670e3eb559adff51a376cd6ec98005philippe allocated by the client. The best we can do is look at the 7838a74d2cc4670e3eb559adff51a376cd6ec98005philippe memory mappings and try to derive some useful information. We 7938a74d2cc4670e3eb559adff51a376cd6ec98005philippe assume that sp starts near its highest possible value, and can 8038a74d2cc4670e3eb559adff51a376cd6ec98005philippe only go down to the start of the mmaped segment. */ 8138a74d2cc4670e3eb559adff51a376cd6ec98005philippe seg = VG_(am_find_nsegment)(sp); 82a2aaa408af37939d4a1db943f8d0d0d232de5186florian if (seg && 83a2aaa408af37939d4a1db943f8d0d0d232de5186florian VG_(am_is_valid_for_client)(sp, 1, VKI_PROT_READ | VKI_PROT_WRITE)) { 8438a74d2cc4670e3eb559adff51a376cd6ec98005philippe tst->client_stack_highest_byte = (Addr)VG_PGROUNDUP(sp)-1; 8538a74d2cc4670e3eb559adff51a376cd6ec98005philippe tst->client_stack_szB = tst->client_stack_highest_byte - seg->start + 1; 8638a74d2cc4670e3eb559adff51a376cd6ec98005philippe 8738a74d2cc4670e3eb559adff51a376cd6ec98005philippe VG_(register_stack)(seg->start, tst->client_stack_highest_byte); 8838a74d2cc4670e3eb559adff51a376cd6ec98005philippe 8938a74d2cc4670e3eb559adff51a376cd6ec98005philippe if (debug) 9038a74d2cc4670e3eb559adff51a376cd6ec98005philippe VG_(printf)("tid %d: guessed client stack range [%#lx-%#lx]\n", 9138a74d2cc4670e3eb559adff51a376cd6ec98005philippe tst->tid, seg->start, tst->client_stack_highest_byte); 9238a74d2cc4670e3eb559adff51a376cd6ec98005philippe } else { 9338a74d2cc4670e3eb559adff51a376cd6ec98005philippe VG_(message)(Vg_UserMsg, 9438a74d2cc4670e3eb559adff51a376cd6ec98005philippe "!? New thread %d starts with SP(%#lx) unmapped\n", 9538a74d2cc4670e3eb559adff51a376cd6ec98005philippe tst->tid, sp); 9638a74d2cc4670e3eb559adff51a376cd6ec98005philippe tst->client_stack_highest_byte = 0; 9738a74d2cc4670e3eb559adff51a376cd6ec98005philippe tst->client_stack_szB = 0; 9838a74d2cc4670e3eb559adff51a376cd6ec98005philippe } 9938a74d2cc4670e3eb559adff51a376cd6ec98005philippe} 10038a74d2cc4670e3eb559adff51a376cd6ec98005philippe 10145f4e7c91119c7d01a59f5e827c67841632c9314sewardj/* Returns True iff address range is something the client can 10245f4e7c91119c7d01a59f5e827c67841632c9314sewardj plausibly mess with: all of it is either already belongs to the 10345f4e7c91119c7d01a59f5e827c67841632c9314sewardj client or is free or a reservation. */ 10445f4e7c91119c7d01a59f5e827c67841632c9314sewardj 1057eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjBool ML_(valid_client_addr)(Addr start, SizeT size, ThreadId tid, 106e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar *syscallname) 1071a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge{ 1081a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge Bool ret; 1091a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 1101a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge if (size == 0) 1111a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge return True; 1121a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 11345f4e7c91119c7d01a59f5e827c67841632c9314sewardj ret = VG_(am_is_valid_for_client_or_free_or_resvn) 11445f4e7c91119c7d01a59f5e827c67841632c9314sewardj (start,size,VKI_PROT_NONE); 1151a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 1161a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge if (0) 117a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("%s: test=%#lx-%#lx ret=%d\n", 11845f4e7c91119c7d01a59f5e827c67841632c9314sewardj syscallname, start, start+size-1, (Int)ret); 1191a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 1201543adfbbb9bf65687148d2c8d5dd7e883dd7769nethercote if (!ret && syscallname != NULL) { 121a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried " 122738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "to modify addresses %#lx-%#lx\n", 123a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart syscallname, start, start+size-1); 1241a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge if (VG_(clo_verbosity) > 1) { 125d01fef7de693582a6ce32bdbef7c9040ad6b356bnjn VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 1261a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge } 1271a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge } 1281a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 1291a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge return ret; 1301a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge} 1311a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 13245f4e7c91119c7d01a59f5e827c67841632c9314sewardj 1337eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjBool ML_(client_signal_OK)(Int sigNo) 134419bbcb905b239dc209da742f976f1c45abf16d0njn{ 135419bbcb905b239dc209da742f976f1c45abf16d0njn /* signal 0 is OK for kill */ 136351d006b8fa2d3ab8cabc362954c42de19aab3c7njn Bool ret = sigNo >= 0 && sigNo <= VG_SIGVGRTUSERMAX; 137419bbcb905b239dc209da742f976f1c45abf16d0njn 138419bbcb905b239dc209da742f976f1c45abf16d0njn //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret); 139419bbcb905b239dc209da742f976f1c45abf16d0njn 140419bbcb905b239dc209da742f976f1c45abf16d0njn return ret; 141419bbcb905b239dc209da742f976f1c45abf16d0njn} 142419bbcb905b239dc209da742f976f1c45abf16d0njn 14345f4e7c91119c7d01a59f5e827c67841632c9314sewardj 14445f4e7c91119c7d01a59f5e827c67841632c9314sewardj/* Handy small function to help stop wrappers from segfaulting when 14545f4e7c91119c7d01a59f5e827c67841632c9314sewardj presented with bogus client addresses. Is not used for generating 14645f4e7c91119c7d01a59f5e827c67841632c9314sewardj user-visible errors. */ 14745f4e7c91119c7d01a59f5e827c67841632c9314sewardj 14845f4e7c91119c7d01a59f5e827c67841632c9314sewardjBool ML_(safe_to_deref) ( void* start, SizeT size ) 14945f4e7c91119c7d01a59f5e827c67841632c9314sewardj{ 150143377eab2ef89c9806a16580c6bf0ae3f8b0834njn return VG_(am_is_valid_for_client)( (Addr)start, size, VKI_PROT_READ ); 15145f4e7c91119c7d01a59f5e827c67841632c9314sewardj} 15245f4e7c91119c7d01a59f5e827c67841632c9314sewardj 15345f4e7c91119c7d01a59f5e827c67841632c9314sewardj 154e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* --------------------------------------------------------------------- 15527ea8bc6721add61e6284cbbf684b7d06a4bd2eenethercote Doing mmap, mremap 156e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn ------------------------------------------------------------------ */ 157de4a1d01951937632098a6cda45859afa587a06fsewardj 158e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* AFAICT from kernel sources (mm/mprotect.c) and general experimentation, 159e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn munmap, mprotect (and mremap??) work at the page level. So addresses 160e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn and lengths must be adjusted for this. */ 161e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 162e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* Mash around start and length so that the area exactly covers 163e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn an integral number of pages. If we don't do that, memcheck's 164e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn idea of addressible memory diverges from that of the 165e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn kernel's, which causes the leak detector to crash. */ 166e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjnstatic 16745f4e7c91119c7d01a59f5e827c67841632c9314sewardjvoid page_align_addr_and_len( Addr* a, SizeT* len) 168de4a1d01951937632098a6cda45859afa587a06fsewardj{ 16998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge Addr ra; 17098abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 17113bfd85dfab2cd301c92e308b274ebd17de830d2njn ra = VG_PGROUNDDN(*a); 17213bfd85dfab2cd301c92e308b274ebd17de830d2njn *len = VG_PGROUNDUP(*a + *len) - ra; 17398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge *a = ra; 174de4a1d01951937632098a6cda45859afa587a06fsewardj} 175de4a1d01951937632098a6cda45859afa587a06fsewardj 176dd3725800151572d32df10ad4df4c8aad0d3d088njnstatic void notify_core_of_mmap(Addr a, SizeT len, UInt prot, 177dd3725800151572d32df10ad4df4c8aad0d3d088njn UInt flags, Int fd, Off64T offset) 178510521e3ad8afb569be39ba46794dbe6e7b65a72bart{ 179510521e3ad8afb569be39ba46794dbe6e7b65a72bart Bool d; 18098abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 18145f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* 'a' is the return value from a real kernel mmap, hence: */ 18245f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(VG_IS_PAGE_ALIGNED(a)); 18345f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* whereas len is whatever the syscall supplied. So: */ 18445f4e7c91119c7d01a59f5e827c67841632c9314sewardj len = VG_PGROUNDUP(len); 185e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 18645f4e7c91119c7d01a59f5e827c67841632c9314sewardj d = VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset ); 187e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 188510521e3ad8afb569be39ba46794dbe6e7b65a72bart if (d) 189ddd61ff058f02059064e083a8accaefed23d5548florian VG_(discard_translations)( a, (ULong)len, 190dd3725800151572d32df10ad4df4c8aad0d3d088njn "notify_core_of_mmap" ); 191510521e3ad8afb569be39ba46794dbe6e7b65a72bart} 192510521e3ad8afb569be39ba46794dbe6e7b65a72bart 193dd3725800151572d32df10ad4df4c8aad0d3d088njnstatic void notify_tool_of_mmap(Addr a, SizeT len, UInt prot, ULong di_handle) 194510521e3ad8afb569be39ba46794dbe6e7b65a72bart{ 195510521e3ad8afb569be39ba46794dbe6e7b65a72bart Bool rr, ww, xx; 196510521e3ad8afb569be39ba46794dbe6e7b65a72bart 197510521e3ad8afb569be39ba46794dbe6e7b65a72bart /* 'a' is the return value from a real kernel mmap, hence: */ 198510521e3ad8afb569be39ba46794dbe6e7b65a72bart vg_assert(VG_IS_PAGE_ALIGNED(a)); 199510521e3ad8afb569be39ba46794dbe6e7b65a72bart /* whereas len is whatever the syscall supplied. So: */ 200510521e3ad8afb569be39ba46794dbe6e7b65a72bart len = VG_PGROUNDUP(len); 201510521e3ad8afb569be39ba46794dbe6e7b65a72bart 20245f4e7c91119c7d01a59f5e827c67841632c9314sewardj rr = toBool(prot & VKI_PROT_READ); 20345f4e7c91119c7d01a59f5e827c67841632c9314sewardj ww = toBool(prot & VKI_PROT_WRITE); 20445f4e7c91119c7d01a59f5e827c67841632c9314sewardj xx = toBool(prot & VKI_PROT_EXEC); 205e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 2069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_TRACK( new_mem_mmap, a, len, rr, ww, xx, di_handle ); 207de4a1d01951937632098a6cda45859afa587a06fsewardj} 208de4a1d01951937632098a6cda45859afa587a06fsewardj 209dd3725800151572d32df10ad4df4c8aad0d3d088njn 210dd3725800151572d32df10ad4df4c8aad0d3d088njn/* When a client mmap has been successfully done, this function must 211dd3725800151572d32df10ad4df4c8aad0d3d088njn be called. It notifies both aspacem and the tool of the new 212dd3725800151572d32df10ad4df4c8aad0d3d088njn mapping. 213dd3725800151572d32df10ad4df4c8aad0d3d088njn 214dd3725800151572d32df10ad4df4c8aad0d3d088njn JRS 2008-Aug-14: But notice this is *very* obscure. The only place 215dd3725800151572d32df10ad4df4c8aad0d3d088njn it is called from is POST(sys_io_setup). In particular, 216dd3725800151572d32df10ad4df4c8aad0d3d088njn ML_(generic_PRE_sys_mmap), in m_syswrap, is the "normal case" handler for 217dd3725800151572d32df10ad4df4c8aad0d3d088njn client mmap. But it doesn't call this function; instead it does the 218dd3725800151572d32df10ad4df4c8aad0d3d088njn relevant notifications itself. Here, we just pass di_handle=0 to 219dd3725800151572d32df10ad4df4c8aad0d3d088njn notify_tool_of_mmap as we have no better information. But really this 220dd3725800151572d32df10ad4df4c8aad0d3d088njn function should be done away with; problem is I don't understand what 221dd3725800151572d32df10ad4df4c8aad0d3d088njn POST(sys_io_setup) does or how it works. 222dd3725800151572d32df10ad4df4c8aad0d3d088njn 223dd3725800151572d32df10ad4df4c8aad0d3d088njn [However, this function is used lots for Darwin, because 224dd3725800151572d32df10ad4df4c8aad0d3d088njn ML_(generic_PRE_sys_mmap) cannot be used for Darwin.] 225dd3725800151572d32df10ad4df4c8aad0d3d088njn */ 226dd3725800151572d32df10ad4df4c8aad0d3d088njnvoid 227dd3725800151572d32df10ad4df4c8aad0d3d088njnML_(notify_core_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot, 228dd3725800151572d32df10ad4df4c8aad0d3d088njn UInt flags, Int fd, Off64T offset ) 229dd3725800151572d32df10ad4df4c8aad0d3d088njn{ 230dd3725800151572d32df10ad4df4c8aad0d3d088njn // XXX: unlike the other notify_core_and_tool* functions, this one doesn't 231dd3725800151572d32df10ad4df4c8aad0d3d088njn // do anything with debug info (ie. it doesn't call VG_(di_notify_mmap)). 232dd3725800151572d32df10ad4df4c8aad0d3d088njn // Should it? --njn 233dd3725800151572d32df10ad4df4c8aad0d3d088njn notify_core_of_mmap(a, len, prot, flags, fd, offset); 234dd3725800151572d32df10ad4df4c8aad0d3d088njn notify_tool_of_mmap(a, len, prot, 0/*di_handle*/); 235dd3725800151572d32df10ad4df4c8aad0d3d088njn} 236dd3725800151572d32df10ad4df4c8aad0d3d088njn 237dd3725800151572d32df10ad4df4c8aad0d3d088njnvoid 238dd3725800151572d32df10ad4df4c8aad0d3d088njnML_(notify_core_and_tool_of_munmap) ( Addr a, SizeT len ) 239dd3725800151572d32df10ad4df4c8aad0d3d088njn{ 240dd3725800151572d32df10ad4df4c8aad0d3d088njn Bool d; 241dd3725800151572d32df10ad4df4c8aad0d3d088njn 242dd3725800151572d32df10ad4df4c8aad0d3d088njn page_align_addr_and_len(&a, &len); 243dd3725800151572d32df10ad4df4c8aad0d3d088njn d = VG_(am_notify_munmap)(a, len); 244dd3725800151572d32df10ad4df4c8aad0d3d088njn VG_TRACK( die_mem_munmap, a, len ); 245dd3725800151572d32df10ad4df4c8aad0d3d088njn VG_(di_notify_munmap)( a, len ); 246dd3725800151572d32df10ad4df4c8aad0d3d088njn if (d) 247ddd61ff058f02059064e083a8accaefed23d5548florian VG_(discard_translations)( a, (ULong)len, 248dd3725800151572d32df10ad4df4c8aad0d3d088njn "ML_(notify_core_and_tool_of_munmap)" ); 249dd3725800151572d32df10ad4df4c8aad0d3d088njn} 250dd3725800151572d32df10ad4df4c8aad0d3d088njn 251dd3725800151572d32df10ad4df4c8aad0d3d088njnvoid 252dd3725800151572d32df10ad4df4c8aad0d3d088njnML_(notify_core_and_tool_of_mprotect) ( Addr a, SizeT len, Int prot ) 253dd3725800151572d32df10ad4df4c8aad0d3d088njn{ 254dd3725800151572d32df10ad4df4c8aad0d3d088njn Bool rr = toBool(prot & VKI_PROT_READ); 255dd3725800151572d32df10ad4df4c8aad0d3d088njn Bool ww = toBool(prot & VKI_PROT_WRITE); 256dd3725800151572d32df10ad4df4c8aad0d3d088njn Bool xx = toBool(prot & VKI_PROT_EXEC); 257dd3725800151572d32df10ad4df4c8aad0d3d088njn Bool d; 258dd3725800151572d32df10ad4df4c8aad0d3d088njn 259dd3725800151572d32df10ad4df4c8aad0d3d088njn page_align_addr_and_len(&a, &len); 260dd3725800151572d32df10ad4df4c8aad0d3d088njn d = VG_(am_notify_mprotect)(a, len, prot); 261dd3725800151572d32df10ad4df4c8aad0d3d088njn VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx ); 262dd3725800151572d32df10ad4df4c8aad0d3d088njn VG_(di_notify_mprotect)( a, len, prot ); 263dd3725800151572d32df10ad4df4c8aad0d3d088njn if (d) 264ddd61ff058f02059064e083a8accaefed23d5548florian VG_(discard_translations)( a, (ULong)len, 265dd3725800151572d32df10ad4df4c8aad0d3d088njn "ML_(notify_core_and_tool_of_mprotect)" ); 266dd3725800151572d32df10ad4df4c8aad0d3d088njn} 267dd3725800151572d32df10ad4df4c8aad0d3d088njn 268dd3725800151572d32df10ad4df4c8aad0d3d088njn 269dd3725800151572d32df10ad4df4c8aad0d3d088njn 270f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if HAVE_MREMAP 27145f4e7c91119c7d01a59f5e827c67841632c9314sewardj/* Expand (or shrink) an existing mapping, potentially moving it at 27245f4e7c91119c7d01a59f5e827c67841632c9314sewardj the same time (controlled by the MREMAP_MAYMOVE flag). Nightmare. 27345f4e7c91119c7d01a59f5e827c67841632c9314sewardj*/ 27445f4e7c91119c7d01a59f5e827c67841632c9314sewardjstatic 27545f4e7c91119c7d01a59f5e827c67841632c9314sewardjSysRes do_mremap( Addr old_addr, SizeT old_len, 27645f4e7c91119c7d01a59f5e827c67841632c9314sewardj Addr new_addr, SizeT new_len, 27745f4e7c91119c7d01a59f5e827c67841632c9314sewardj UWord flags, ThreadId tid ) 2781a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge{ 27945f4e7c91119c7d01a59f5e827c67841632c9314sewardj# define MIN_SIZET(_aa,_bb) (_aa) < (_bb) ? (_aa) : (_bb) 2801a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 28145f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool ok, d; 282ef1cf8b3583107c7d918c60895937f09969d5b3esewardj NSegment const* old_seg; 28345f4e7c91119c7d01a59f5e827c67841632c9314sewardj Addr advised; 28445f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool f_fixed = toBool(flags & VKI_MREMAP_FIXED); 28545f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool f_maymove = toBool(flags & VKI_MREMAP_MAYMOVE); 2861a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 28745f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (0) 288a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("do_remap (old %#lx %ld) (new %#lx %ld) %s %s\n", 28945f4e7c91119c7d01a59f5e827c67841632c9314sewardj old_addr,old_len,new_addr,new_len, 29045f4e7c91119c7d01a59f5e827c67841632c9314sewardj flags & VKI_MREMAP_MAYMOVE ? "MAYMOVE" : "", 29145f4e7c91119c7d01a59f5e827c67841632c9314sewardj flags & VKI_MREMAP_FIXED ? "FIXED" : ""); 29263a622f4da0254c435348f2c78b31aa66f4549c8sewardj if (0) 29363a622f4da0254c435348f2c78b31aa66f4549c8sewardj VG_(am_show_nsegments)(0, "do_remap: before"); 2941a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 29545f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (flags & ~(VKI_MREMAP_FIXED | VKI_MREMAP_MAYMOVE)) 29645f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 2971a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 29845f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!VG_IS_PAGE_ALIGNED(old_addr)) 29945f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3001a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 30145f4e7c91119c7d01a59f5e827c67841632c9314sewardj old_len = VG_PGROUNDUP(old_len); 30245f4e7c91119c7d01a59f5e827c67841632c9314sewardj new_len = VG_PGROUNDUP(new_len); 3031a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 30445f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len == 0) 30545f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3061a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 30745f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* kernel doesn't reject this, but we do. */ 30845f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (old_len == 0) 30945f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3101a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 31145f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* reject wraparounds */ 312a5e13dd485bb5d5a39bcb595715eaaa11653b544tom if (old_addr + old_len < old_addr) 313a5e13dd485bb5d5a39bcb595715eaaa11653b544tom goto eINVAL; 314a5e13dd485bb5d5a39bcb595715eaaa11653b544tom if (f_fixed == True && new_addr + new_len < new_len) 31545f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3161a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 31745f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* kernel rejects all fixed, no-move requests (which are 31845f4e7c91119c7d01a59f5e827c67841632c9314sewardj meaningless). */ 31945f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (f_fixed == True && f_maymove == False) 32045f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3211a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 32245f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* Stay away from non-client areas. */ 32345f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!ML_(valid_client_addr)(old_addr, old_len, tid, "mremap(old_addr)")) 32445f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3251a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 32645f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* In all remaining cases, if the old range does not fall within a 32745f4e7c91119c7d01a59f5e827c67841632c9314sewardj single segment, fail. */ 32845f4e7c91119c7d01a59f5e827c67841632c9314sewardj old_seg = VG_(am_find_nsegment)( old_addr ); 32945f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (old_addr < old_seg->start || old_addr+old_len-1 > old_seg->end) 33045f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 331c290b883f9a9386a925a8c24f4dc2e59a8851c5aflorian if (old_seg->kind != SkAnonC && old_seg->kind != SkFileC && 332c290b883f9a9386a925a8c24f4dc2e59a8851c5aflorian old_seg->kind != SkShmC) 33345f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 3341a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 33545f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(old_len > 0); 33645f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(new_len > 0); 33745f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(VG_IS_PAGE_ALIGNED(old_len)); 33845f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(VG_IS_PAGE_ALIGNED(new_len)); 33945f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(VG_IS_PAGE_ALIGNED(old_addr)); 3401a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 34145f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* There are 3 remaining cases: 3421a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 34345f4e7c91119c7d01a59f5e827c67841632c9314sewardj * maymove == False 3441a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 34545f4e7c91119c7d01a59f5e827c67841632c9314sewardj new space has to be at old address, so: 34645f4e7c91119c7d01a59f5e827c67841632c9314sewardj - shrink -> unmap end 34745f4e7c91119c7d01a59f5e827c67841632c9314sewardj - same size -> do nothing 34845f4e7c91119c7d01a59f5e827c67841632c9314sewardj - grow -> if can grow in-place, do so, else fail 3491a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 35045f4e7c91119c7d01a59f5e827c67841632c9314sewardj * maymove == True, fixed == False 3511a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 35245f4e7c91119c7d01a59f5e827c67841632c9314sewardj new space can be anywhere, so: 35345f4e7c91119c7d01a59f5e827c67841632c9314sewardj - shrink -> unmap end 35445f4e7c91119c7d01a59f5e827c67841632c9314sewardj - same size -> do nothing 35545f4e7c91119c7d01a59f5e827c67841632c9314sewardj - grow -> if can grow in-place, do so, else 35645f4e7c91119c7d01a59f5e827c67841632c9314sewardj move to anywhere large enough, else fail 357e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 35845f4e7c91119c7d01a59f5e827c67841632c9314sewardj * maymove == True, fixed == True 3591a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 36045f4e7c91119c7d01a59f5e827c67841632c9314sewardj new space must be at new address, so: 3611a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 36245f4e7c91119c7d01a59f5e827c67841632c9314sewardj - if new address is not page aligned, fail 36345f4e7c91119c7d01a59f5e827c67841632c9314sewardj - if new address range overlaps old one, fail 36445f4e7c91119c7d01a59f5e827c67841632c9314sewardj - if new address range cannot be allocated, fail 36545f4e7c91119c7d01a59f5e827c67841632c9314sewardj - else move to new address range with new size 36645f4e7c91119c7d01a59f5e827c67841632c9314sewardj - else fail 36745f4e7c91119c7d01a59f5e827c67841632c9314sewardj */ 3681a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 36945f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (f_maymove == False) { 37045f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* new space has to be at old address */ 37145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len < old_len) 37245f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto shrink_in_place; 37345f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len > old_len) 37445f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto grow_in_place_or_fail; 37545f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto same_in_place; 37645f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 3771a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 37845f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (f_maymove == True && f_fixed == False) { 37945f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* new space can be anywhere */ 38045f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len < old_len) 38145f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto shrink_in_place; 38245f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len > old_len) 38345f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto grow_in_place_or_move_anywhere_or_fail; 38445f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto same_in_place; 38545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 3861a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 38745f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (f_maymove == True && f_fixed == True) { 38845f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* new space can only be at the new address */ 38945f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!VG_IS_PAGE_ALIGNED(new_addr)) 39045f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 39145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_addr+new_len-1 < old_addr || new_addr > old_addr+old_len-1) { 39245f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* no overlap */ 3931a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge } else { 39445f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 39545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 39645f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_addr == 0) 39745f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eINVAL; 39845f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* VG_(am_get_advisory_client_simple) interprets zero to mean 39945f4e7c91119c7d01a59f5e827c67841632c9314sewardj non-fixed, which is not what we want */ 40045f4e7c91119c7d01a59f5e827c67841632c9314sewardj advised = VG_(am_get_advisory_client_simple)(new_addr, new_len, &ok); 40145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!ok || advised != new_addr) 40245f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eNOMEM; 40345f4e7c91119c7d01a59f5e827c67841632c9314sewardj ok = VG_(am_relocate_nooverlap_client) 40445f4e7c91119c7d01a59f5e827c67841632c9314sewardj ( &d, old_addr, old_len, new_addr, new_len ); 40545f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (ok) { 40645f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( copy_mem_remap, old_addr, new_addr, 40745f4e7c91119c7d01a59f5e827c67841632c9314sewardj MIN_SIZET(old_len,new_len) ); 40845f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len > old_len) 40945f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len, 4109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj old_seg->hasR, old_seg->hasW, old_seg->hasX, 4119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 0/*di_handle*/ ); 41245f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK(die_mem_munmap, old_addr, old_len); 41345f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (d) { 41445f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(discard_translations)( old_addr, old_len, "do_remap(1)" ); 41545f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(discard_translations)( new_addr, new_len, "do_remap(2)" ); 41645f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 41745f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Success)( new_addr ); 41845f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 41945f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eNOMEM; 42045f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 4211a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 42245f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* end of the 3 cases */ 42345f4e7c91119c7d01a59f5e827c67841632c9314sewardj /*NOTREACHED*/ vg_assert(0); 42445f4e7c91119c7d01a59f5e827c67841632c9314sewardj 42545f4e7c91119c7d01a59f5e827c67841632c9314sewardj grow_in_place_or_move_anywhere_or_fail: 42645f4e7c91119c7d01a59f5e827c67841632c9314sewardj { 42745f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* try growing it in-place */ 42845f4e7c91119c7d01a59f5e827c67841632c9314sewardj Addr needA = old_addr + old_len; 42945f4e7c91119c7d01a59f5e827c67841632c9314sewardj SSizeT needL = new_len - old_len; 43045f4e7c91119c7d01a59f5e827c67841632c9314sewardj 43145f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(needL > 0); 4320b41f3210759573ae126ca1e84e1dd6fb939ab15florian vg_assert(needA > 0); 4330b41f3210759573ae126ca1e84e1dd6fb939ab15florian 43445f4e7c91119c7d01a59f5e827c67841632c9314sewardj advised = VG_(am_get_advisory_client_simple)( needA, needL, &ok ); 43563a622f4da0254c435348f2c78b31aa66f4549c8sewardj if (ok) { 43615e301e2b0540fea8dd8b5410bf75d2fa0e8eac1philippe /* Fixes bug #129866. */ 43715e301e2b0540fea8dd8b5410bf75d2fa0e8eac1philippe ok = VG_(am_covered_by_single_free_segment) ( needA, needL ); 43863a622f4da0254c435348f2c78b31aa66f4549c8sewardj } 43945f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (ok && advised == needA) { 440dd7318bea2a008f15085e12e026a78a6802e2e9cflorian const NSegment *new_seg = VG_(am_extend_map_client)( old_addr, needL ); 441dd7318bea2a008f15085e12e026a78a6802e2e9cflorian if (new_seg) { 44245f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( new_mem_mmap, needA, needL, 443dd7318bea2a008f15085e12e026a78a6802e2e9cflorian new_seg->hasR, 444dd7318bea2a008f15085e12e026a78a6802e2e9cflorian new_seg->hasW, new_seg->hasX, 4459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 0/*di_handle*/ ); 44645f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Success)( old_addr ); 44745f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 44845f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 4491a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 45045f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* that failed. Look elsewhere. */ 45145f4e7c91119c7d01a59f5e827c67841632c9314sewardj advised = VG_(am_get_advisory_client_simple)( 0, new_len, &ok ); 45245f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (ok) { 4535484f384b88050235e204ce5aa5d3cf72d7c5580tom Bool oldR = old_seg->hasR; 4545484f384b88050235e204ce5aa5d3cf72d7c5580tom Bool oldW = old_seg->hasW; 4555484f384b88050235e204ce5aa5d3cf72d7c5580tom Bool oldX = old_seg->hasX; 45645f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* assert new area does not overlap old */ 45745f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(advised+new_len-1 < old_addr 45845f4e7c91119c7d01a59f5e827c67841632c9314sewardj || advised > old_addr+old_len-1); 45945f4e7c91119c7d01a59f5e827c67841632c9314sewardj ok = VG_(am_relocate_nooverlap_client) 46045f4e7c91119c7d01a59f5e827c67841632c9314sewardj ( &d, old_addr, old_len, advised, new_len ); 46145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (ok) { 46245f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( copy_mem_remap, old_addr, advised, 46345f4e7c91119c7d01a59f5e827c67841632c9314sewardj MIN_SIZET(old_len,new_len) ); 46445f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (new_len > old_len) 46545f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( new_mem_mmap, advised+old_len, new_len-old_len, 4665484f384b88050235e204ce5aa5d3cf72d7c5580tom oldR, oldW, oldX, 0/*di_handle*/ ); 46745f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK(die_mem_munmap, old_addr, old_len); 46845f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (d) { 46945f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(discard_translations)( old_addr, old_len, "do_remap(4)" ); 47045f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(discard_translations)( advised, new_len, "do_remap(5)" ); 47145f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 47245f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Success)( advised ); 47345f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 47445f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 47545f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eNOMEM; 47645f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 47745f4e7c91119c7d01a59f5e827c67841632c9314sewardj /*NOTREACHED*/ vg_assert(0); 4781a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 47945f4e7c91119c7d01a59f5e827c67841632c9314sewardj grow_in_place_or_fail: 48045f4e7c91119c7d01a59f5e827c67841632c9314sewardj { 48145f4e7c91119c7d01a59f5e827c67841632c9314sewardj Addr needA = old_addr + old_len; 48245f4e7c91119c7d01a59f5e827c67841632c9314sewardj SizeT needL = new_len - old_len; 4830b41f3210759573ae126ca1e84e1dd6fb939ab15florian 4840b41f3210759573ae126ca1e84e1dd6fb939ab15florian vg_assert(needA > 0); 4850b41f3210759573ae126ca1e84e1dd6fb939ab15florian 48645f4e7c91119c7d01a59f5e827c67841632c9314sewardj advised = VG_(am_get_advisory_client_simple)( needA, needL, &ok ); 48763a622f4da0254c435348f2c78b31aa66f4549c8sewardj if (ok) { 48815e301e2b0540fea8dd8b5410bf75d2fa0e8eac1philippe /* Fixes bug #129866. */ 48915e301e2b0540fea8dd8b5410bf75d2fa0e8eac1philippe ok = VG_(am_covered_by_single_free_segment) ( needA, needL ); 49063a622f4da0254c435348f2c78b31aa66f4549c8sewardj } 49145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!ok || advised != needA) 49245f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eNOMEM; 493dd7318bea2a008f15085e12e026a78a6802e2e9cflorian const NSegment *new_seg = VG_(am_extend_map_client)( old_addr, needL ); 494dd7318bea2a008f15085e12e026a78a6802e2e9cflorian if (!new_seg) 49545f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto eNOMEM; 49645f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( new_mem_mmap, needA, needL, 497dd7318bea2a008f15085e12e026a78a6802e2e9cflorian new_seg->hasR, new_seg->hasW, new_seg->hasX, 4989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 0/*di_handle*/ ); 499dd7318bea2a008f15085e12e026a78a6802e2e9cflorian 50045f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Success)( old_addr ); 50145f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 50245f4e7c91119c7d01a59f5e827c67841632c9314sewardj /*NOTREACHED*/ vg_assert(0); 5031a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 50445f4e7c91119c7d01a59f5e827c67841632c9314sewardj shrink_in_place: 50545f4e7c91119c7d01a59f5e827c67841632c9314sewardj { 50645f4e7c91119c7d01a59f5e827c67841632c9314sewardj SysRes sres = VG_(am_munmap_client)( &d, old_addr+new_len, old_len-new_len ); 507cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(sres)) 50845f4e7c91119c7d01a59f5e827c67841632c9314sewardj return sres; 50945f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_TRACK( die_mem_munmap, old_addr+new_len, old_len-new_len ); 51045f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (d) 51145f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(discard_translations)( old_addr+new_len, old_len-new_len, 51245f4e7c91119c7d01a59f5e827c67841632c9314sewardj "do_remap(7)" ); 51345f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Success)( old_addr ); 514e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 51545f4e7c91119c7d01a59f5e827c67841632c9314sewardj /*NOTREACHED*/ vg_assert(0); 5161a30304e41211cac4b0f368e1a419925a9a38774fitzhardinge 51745f4e7c91119c7d01a59f5e827c67841632c9314sewardj same_in_place: 51845f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Success)( old_addr ); 51945f4e7c91119c7d01a59f5e827c67841632c9314sewardj /*NOTREACHED*/ vg_assert(0); 52045f4e7c91119c7d01a59f5e827c67841632c9314sewardj 52145f4e7c91119c7d01a59f5e827c67841632c9314sewardj eINVAL: 52245f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Error)( VKI_EINVAL ); 52345f4e7c91119c7d01a59f5e827c67841632c9314sewardj eNOMEM: 52445f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(mk_SysRes_Error)( VKI_ENOMEM ); 52545f4e7c91119c7d01a59f5e827c67841632c9314sewardj 52645f4e7c91119c7d01a59f5e827c67841632c9314sewardj# undef MIN_SIZET 527de4a1d01951937632098a6cda45859afa587a06fsewardj} 528f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* HAVE_MREMAP */ 529de4a1d01951937632098a6cda45859afa587a06fsewardj 530de4a1d01951937632098a6cda45859afa587a06fsewardj 531a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj/* --------------------------------------------------------------------- 532a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj File-descriptor tracking 533a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ------------------------------------------------------------------ */ 534de4a1d01951937632098a6cda45859afa587a06fsewardj 535f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* One of these is allocated for each open file descriptor. */ 536f5f536f398c082b8c92b2789a90d83b34ab98660rjwalshtypedef struct OpenFd 537f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 538f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh Int fd; /* The file descriptor */ 53919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar *pathname; /* NULL if not a regular file or unknown */ 540f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh ExeContext *where; /* NULL if inherited from parent */ 541f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh struct OpenFd *next, *prev; 542f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} OpenFd; 543f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 544f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* List of allocated file descriptors. */ 5451aa40211ec688cb47df0341e770fb59e933d5b5csewardjstatic OpenFd *allocated_fds = NULL; 546f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 547f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* Count of open file descriptors. */ 5480a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardjstatic Int fd_count = 0; 549f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 550f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 551f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* Note the fact that a file descriptor was just closed. */ 552f5f536f398c082b8c92b2789a90d83b34ab98660rjwalshstatic 5531dcee097db02f9ef3ba355162c4373d90d0e895cnjnvoid record_fd_close(Int fd) 554f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 555f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh OpenFd *i = allocated_fds; 556f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 557ad1c9563ffd6bbc7d617776256b65a924fd0130ethughes if (fd >= VG_(fd_hard_limit)) 55802665ba6d0b25f8e0685ead136173091ceaa2701rjwalsh return; /* Valgrind internal */ 55902665ba6d0b25f8e0685ead136173091ceaa2701rjwalsh 560f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh while(i) { 561f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(i->fd == fd) { 562f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(i->prev) 563f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i->prev->next = i->next; 564f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh else 565f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh allocated_fds = i->next; 566f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(i->next) 567f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i->next->prev = i->prev; 568f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(i->pathname) 56977eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(free) (i->pathname); 57077eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(free) (i); 571f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh fd_count--; 572f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh break; 573f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 574f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i = i->next; 575f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 576f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 577f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 578f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* Note the fact that a file descriptor was just opened. If the 579f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh tid is -1, this indicates an inherited fd. If the pathname is NULL, 580f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh this either indicates a non-standard file (i.e. a pipe or socket or 581f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh some such thing) or that we don't know the filename. If the fd is 582f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh already open, then we're probably doing a dup2() to an existing fd, 583f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh so just overwrite the existing one. */ 5843130eab8c67d0c720cb1a86906cc057daa9700ccflorianvoid ML_(record_fd_open_with_given_name)(ThreadId tid, Int fd, 5853130eab8c67d0c720cb1a86906cc057daa9700ccflorian const HChar *pathname) 586f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 587f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh OpenFd *i; 588f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 589ad1c9563ffd6bbc7d617776256b65a924fd0130ethughes if (fd >= VG_(fd_hard_limit)) 5900e8bfcfee9fbbe6ab13f5c6ebe7ffd1098e21ff9fitzhardinge return; /* Valgrind internal */ 5910e8bfcfee9fbbe6ab13f5c6ebe7ffd1098e21ff9fitzhardinge 592f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh /* Check to see if this fd is already open. */ 593f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i = allocated_fds; 594f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh while (i) { 595f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if (i->fd == fd) { 59677eb20b3865e7b17c7695c7e7a526b52935f593eflorian if (i->pathname) VG_(free)(i->pathname); 597f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh break; 598f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 599f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i = i->next; 600f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 601f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 602f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh /* Not already one: allocate an OpenFd */ 603f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if (i == NULL) { 60477eb20b3865e7b17c7695c7e7a526b52935f593eflorian i = VG_(malloc)("syswrap.rfdowgn.1", sizeof(OpenFd)); 605f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 606f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i->prev = NULL; 607f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i->next = allocated_fds; 608f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(allocated_fds) allocated_fds->prev = i; 609f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh allocated_fds = i; 610f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh fd_count++; 611f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 612f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 613f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i->fd = fd; 61477eb20b3865e7b17c7695c7e7a526b52935f593eflorian i->pathname = VG_(strdup)("syswrap.rfdowgn.2", pathname); 615d01b5983189559779de756e32d15d9926b9f61f3sewardj i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid, 0/*first_ip_delta*/); 616f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 617f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 618f845f8ffb1d2fac86714e32f4e279700b07722dfnjn// Record opening of an fd, and find its name. 619096ccdd670d4e4eabdafb18598b1cd06d790fda8njnvoid ML_(record_fd_open_named)(ThreadId tid, Int fd) 620f845f8ffb1d2fac86714e32f4e279700b07722dfnjn{ 6213130eab8c67d0c720cb1a86906cc057daa9700ccflorian const HChar* buf; 6223130eab8c67d0c720cb1a86906cc057daa9700ccflorian const HChar* name; 623a175ffb9ffa4fd250611582a611333d11c835de2florian if (VG_(resolve_filename)(fd, &buf)) 624f845f8ffb1d2fac86714e32f4e279700b07722dfnjn name = buf; 625f845f8ffb1d2fac86714e32f4e279700b07722dfnjn else 626f845f8ffb1d2fac86714e32f4e279700b07722dfnjn name = NULL; 627f845f8ffb1d2fac86714e32f4e279700b07722dfnjn 6284279a8884ad1aee46dfe34b5df5950b51e93532cnjn ML_(record_fd_open_with_given_name)(tid, fd, name); 629f845f8ffb1d2fac86714e32f4e279700b07722dfnjn} 630f845f8ffb1d2fac86714e32f4e279700b07722dfnjn 631f845f8ffb1d2fac86714e32f4e279700b07722dfnjn// Record opening of a nameless fd. 632f845f8ffb1d2fac86714e32f4e279700b07722dfnjnvoid ML_(record_fd_open_nameless)(ThreadId tid, Int fd) 633f845f8ffb1d2fac86714e32f4e279700b07722dfnjn{ 6344279a8884ad1aee46dfe34b5df5950b51e93532cnjn ML_(record_fd_open_with_given_name)(tid, fd, NULL); 635f845f8ffb1d2fac86714e32f4e279700b07722dfnjn} 636f845f8ffb1d2fac86714e32f4e279700b07722dfnjn 637f5f536f398c082b8c92b2789a90d83b34ab98660rjwalshstatic 6383995526f11b6633bdf3eed0255c62a42f50461b4tomHChar *unix_to_name(struct vki_sockaddr_un *sa, UInt len, HChar *name) 639f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 64073b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (sa == NULL || len == 0 || sa->sun_path[0] == '\0') { 641f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh VG_(sprintf)(name, "<unknown>"); 642f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 643f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh VG_(sprintf)(name, "%s", sa->sun_path); 644f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 645f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 646f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh return name; 647f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 648f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 649f5f536f398c082b8c92b2789a90d83b34ab98660rjwalshstatic 6503995526f11b6633bdf3eed0255c62a42f50461b4tomHChar *inet_to_name(struct vki_sockaddr_in *sa, UInt len, HChar *name) 651f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 65273b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (sa == NULL || len == 0) { 653f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh VG_(sprintf)(name, "<unknown>"); 6543995526f11b6633bdf3eed0255c62a42f50461b4tom } else if (sa->sin_port == 0) { 6553995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(sprintf)(name, "<unbound>"); 656f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 657329af4bc87f417b5ce3d770da3ebfbadb88904f2tom UInt addr = VG_(ntohl)(sa->sin_addr.s_addr); 6583995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(sprintf)(name, "%u.%u.%u.%u:%u", 6593995526f11b6633bdf3eed0255c62a42f50461b4tom (addr>>24) & 0xFF, (addr>>16) & 0xFF, 6603995526f11b6633bdf3eed0255c62a42f50461b4tom (addr>>8) & 0xFF, addr & 0xFF, 6613995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(ntohs)(sa->sin_port)); 6623995526f11b6633bdf3eed0255c62a42f50461b4tom } 6633995526f11b6633bdf3eed0255c62a42f50461b4tom 6643995526f11b6633bdf3eed0255c62a42f50461b4tom return name; 6653995526f11b6633bdf3eed0255c62a42f50461b4tom} 6663995526f11b6633bdf3eed0255c62a42f50461b4tom 6673995526f11b6633bdf3eed0255c62a42f50461b4tomstatic 6683995526f11b6633bdf3eed0255c62a42f50461b4tomvoid inet6_format(HChar *s, const UChar ip[16]) 6693995526f11b6633bdf3eed0255c62a42f50461b4tom{ 6703995526f11b6633bdf3eed0255c62a42f50461b4tom static const unsigned char V4mappedprefix[12] = {0,0,0,0,0,0,0,0,0,0,0xff,0xff}; 6713995526f11b6633bdf3eed0255c62a42f50461b4tom 6723995526f11b6633bdf3eed0255c62a42f50461b4tom if (!VG_(memcmp)(ip, V4mappedprefix, 12)) { 6738eebf23c35d97489c0d3c8b41dd542e00ae6acbdflorian const struct vki_in_addr *sin_addr = 6748eebf23c35d97489c0d3c8b41dd542e00ae6acbdflorian (const struct vki_in_addr *)(ip + 12); 6753995526f11b6633bdf3eed0255c62a42f50461b4tom UInt addr = VG_(ntohl)(sin_addr->s_addr); 6763995526f11b6633bdf3eed0255c62a42f50461b4tom 6773995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(sprintf)(s, "::ffff:%u.%u.%u.%u", 6783995526f11b6633bdf3eed0255c62a42f50461b4tom (addr>>24) & 0xFF, (addr>>16) & 0xFF, 6793995526f11b6633bdf3eed0255c62a42f50461b4tom (addr>>8) & 0xFF, addr & 0xFF); 6803995526f11b6633bdf3eed0255c62a42f50461b4tom } else { 6813995526f11b6633bdf3eed0255c62a42f50461b4tom Bool compressing = False; 6823995526f11b6633bdf3eed0255c62a42f50461b4tom Bool compressed = False; 6833995526f11b6633bdf3eed0255c62a42f50461b4tom Int len = 0; 6843995526f11b6633bdf3eed0255c62a42f50461b4tom Int i; 6853995526f11b6633bdf3eed0255c62a42f50461b4tom 6863995526f11b6633bdf3eed0255c62a42f50461b4tom for (i = 0; i < 16; i += 2) { 6873995526f11b6633bdf3eed0255c62a42f50461b4tom UInt word = ((UInt)ip[i] << 8) | (UInt)ip[i+1]; 6883995526f11b6633bdf3eed0255c62a42f50461b4tom if (word == 0 && !compressed) { 6893995526f11b6633bdf3eed0255c62a42f50461b4tom compressing = True; 6903995526f11b6633bdf3eed0255c62a42f50461b4tom } else { 6913995526f11b6633bdf3eed0255c62a42f50461b4tom if (compressing) { 6923995526f11b6633bdf3eed0255c62a42f50461b4tom compressing = False; 6933995526f11b6633bdf3eed0255c62a42f50461b4tom compressed = True; 6943995526f11b6633bdf3eed0255c62a42f50461b4tom s[len++] = ':'; 6953995526f11b6633bdf3eed0255c62a42f50461b4tom } 6963995526f11b6633bdf3eed0255c62a42f50461b4tom if (i > 0) { 6973995526f11b6633bdf3eed0255c62a42f50461b4tom s[len++] = ':'; 6983995526f11b6633bdf3eed0255c62a42f50461b4tom } 6993995526f11b6633bdf3eed0255c62a42f50461b4tom len += VG_(sprintf)(s + len, "%x", word); 7003995526f11b6633bdf3eed0255c62a42f50461b4tom } 7013995526f11b6633bdf3eed0255c62a42f50461b4tom } 7023995526f11b6633bdf3eed0255c62a42f50461b4tom 7033995526f11b6633bdf3eed0255c62a42f50461b4tom if (compressing) { 7043995526f11b6633bdf3eed0255c62a42f50461b4tom s[len++] = ':'; 7053995526f11b6633bdf3eed0255c62a42f50461b4tom s[len++] = ':'; 706f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 7073995526f11b6633bdf3eed0255c62a42f50461b4tom 7083995526f11b6633bdf3eed0255c62a42f50461b4tom s[len++] = 0; 7093995526f11b6633bdf3eed0255c62a42f50461b4tom } 7103995526f11b6633bdf3eed0255c62a42f50461b4tom 7113995526f11b6633bdf3eed0255c62a42f50461b4tom return; 7123995526f11b6633bdf3eed0255c62a42f50461b4tom} 7133995526f11b6633bdf3eed0255c62a42f50461b4tom 7143995526f11b6633bdf3eed0255c62a42f50461b4tomstatic 7153995526f11b6633bdf3eed0255c62a42f50461b4tomHChar *inet6_to_name(struct vki_sockaddr_in6 *sa, UInt len, HChar *name) 7163995526f11b6633bdf3eed0255c62a42f50461b4tom{ 7173995526f11b6633bdf3eed0255c62a42f50461b4tom if (sa == NULL || len == 0) { 7183995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(sprintf)(name, "<unknown>"); 7193995526f11b6633bdf3eed0255c62a42f50461b4tom } else if (sa->sin6_port == 0) { 7203995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(sprintf)(name, "<unbound>"); 7213995526f11b6633bdf3eed0255c62a42f50461b4tom } else { 722f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar addr[100]; // large enough 7233995526f11b6633bdf3eed0255c62a42f50461b4tom inet6_format(addr, (void *)&(sa->sin6_addr)); 7243995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(sprintf)(name, "[%s]:%u", addr, VG_(ntohs)(sa->sin6_port)); 725f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 726f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 727f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh return name; 728f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 729f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 730f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* 731f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh * Try get some details about a socket. 732f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh */ 733f5f536f398c082b8c92b2789a90d83b34ab98660rjwalshstatic void 7340a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardjgetsockdetails(Int fd) 735f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 736f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh union u { 73773b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_sockaddr a; 73873b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_sockaddr_in in; 7393995526f11b6633bdf3eed0255c62a42f50461b4tom struct vki_sockaddr_in6 in6; 74073b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_sockaddr_un un; 741f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } laddr; 7421636d33c13958b9c0e7d3059cdd5005746418eb2florian Int llen; 743f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 744f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh llen = sizeof(laddr); 745f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh VG_(memset)(&laddr, 0, llen); 746f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 747f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(VG_(getsockname)(fd, (struct vki_sockaddr *)&(laddr.a), &llen) != -1) { 748f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh switch(laddr.a.sa_family) { 74973b526fb4af0f60634f0078583d92b931d5c0eebnethercote case VKI_AF_INET: { 750f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar lname[32]; // large enough 751f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar pname[32]; // large enough 75273b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_sockaddr_in paddr; 7531636d33c13958b9c0e7d3059cdd5005746418eb2florian Int plen = sizeof(struct vki_sockaddr_in); 754f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 755738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) { 756738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> %s\n", fd, 7573995526f11b6633bdf3eed0255c62a42f50461b4tom inet_to_name(&(laddr.in), llen, lname), 7583995526f11b6633bdf3eed0255c62a42f50461b4tom inet_to_name(&paddr, plen, pname)); 759f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 760738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open AF_INET socket %d: %s <-> unbound\n", 7613995526f11b6633bdf3eed0255c62a42f50461b4tom fd, inet_to_name(&(laddr.in), llen, lname)); 7623995526f11b6633bdf3eed0255c62a42f50461b4tom } 7633995526f11b6633bdf3eed0255c62a42f50461b4tom return; 7643995526f11b6633bdf3eed0255c62a42f50461b4tom } 7653995526f11b6633bdf3eed0255c62a42f50461b4tom case VKI_AF_INET6: { 766f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar lname[128]; // large enough 767f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar pname[128]; // large enough 7683995526f11b6633bdf3eed0255c62a42f50461b4tom struct vki_sockaddr_in6 paddr; 7693995526f11b6633bdf3eed0255c62a42f50461b4tom Int plen = sizeof(struct vki_sockaddr_in6); 7703995526f11b6633bdf3eed0255c62a42f50461b4tom 7713995526f11b6633bdf3eed0255c62a42f50461b4tom if (VG_(getpeername)(fd, (struct vki_sockaddr *)&paddr, &plen) != -1) { 7723995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(message)(Vg_UserMsg, "Open AF_INET6 socket %d: %s <-> %s\n", fd, 7733995526f11b6633bdf3eed0255c62a42f50461b4tom inet6_to_name(&(laddr.in6), llen, lname), 7743995526f11b6633bdf3eed0255c62a42f50461b4tom inet6_to_name(&paddr, plen, pname)); 7753995526f11b6633bdf3eed0255c62a42f50461b4tom } else { 7763995526f11b6633bdf3eed0255c62a42f50461b4tom VG_(message)(Vg_UserMsg, "Open AF_INET6 socket %d: %s <-> unbound\n", 7773995526f11b6633bdf3eed0255c62a42f50461b4tom fd, inet6_to_name(&(laddr.in6), llen, lname)); 778f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 779f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh return; 780f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 78173b526fb4af0f60634f0078583d92b931d5c0eebnethercote case VKI_AF_UNIX: { 782f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh static char lname[256]; 783738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open AF_UNIX socket %d: %s\n", fd, 7843995526f11b6633bdf3eed0255c62a42f50461b4tom unix_to_name(&(laddr.un), llen, lname)); 785f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh return; 786f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 787f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh default: 788738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open pf-%d socket %d:\n", 789f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh laddr.a.sa_family, fd); 790f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh return; 791f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 792f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 793f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 794738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open socket %d:\n", fd); 795f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 796f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 797f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 7983a42fb88cfb660772c77ef010708a2b21f501980nethercote/* Dump out a summary, and a more detailed list, of open file descriptors. */ 799e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianvoid VG_(show_open_fds) (const HChar* when) 800f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 801f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh OpenFd *i = allocated_fds; 802f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 803c3360388cc73eff2327d40d5f3ed313b9e548591philippe VG_(message)(Vg_UserMsg, "FILE DESCRIPTORS: %d open %s.\n", fd_count, when); 804f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 805738856f99eea33d86ce91dcb1d6cd5b151e307casewardj while (i) { 806738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (i->pathname) { 807738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open file descriptor %d: %s\n", i->fd, 808f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i->pathname); 809f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 8100a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj Int val; 8111636d33c13958b9c0e7d3059cdd5005746418eb2florian Int len = sizeof(val); 812f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 813738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (VG_(getsockopt)(i->fd, VKI_SOL_SOCKET, VKI_SO_TYPE, &val, &len) 814738856f99eea33d86ce91dcb1d6cd5b151e307casewardj == -1) { 815738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "Open file descriptor %d:\n", i->fd); 816f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 817f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh getsockdetails(i->fd); 818f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 819f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 820f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 821f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(i->where) { 822f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh VG_(pp_ExeContext)(i->where); 823738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 824f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 825738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, " <inherited from parent>\n"); 826738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 827f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 828f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 829f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh i = i->next; 830f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 831f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 832738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "\n"); 833f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 834f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 83581b975ce84471039f9d668274fd544419541ebabnjn/* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't 83681b975ce84471039f9d668274fd544419541ebabnjn have /proc support compiled in, or a non-Linux kernel), then we need to 83781b975ce84471039f9d668274fd544419541ebabnjn find out what file descriptors we inherited from our parent process the 83881b975ce84471039f9d668274fd544419541ebabnjn hard way - by checking each fd in turn. */ 839f5f536f398c082b8c92b2789a90d83b34ab98660rjwalshstatic 84081b975ce84471039f9d668274fd544419541ebabnjnvoid init_preopened_fds_without_proc_self_fd(void) 841f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 842f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh struct vki_rlimit lim; 8430a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj UInt count; 8440a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj Int i; 845f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 846620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) { 847f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh /* Hmm. getrlimit() failed. Now we're screwed, so just choose 848f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh an arbitrarily high number. 1024 happens to be the limit in 84981b975ce84471039f9d668274fd544419541ebabnjn the 2.4 Linux kernels. */ 850f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh count = 1024; 851f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 852f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh count = lim.rlim_cur; 853f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 854f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 855f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh for (i = 0; i < count; i++) 85681b975ce84471039f9d668274fd544419541ebabnjn if (VG_(fcntl)(i, VKI_F_GETFL, 0) != -1) 85781b975ce84471039f9d668274fd544419541ebabnjn ML_(record_fd_open_named)(-1, i); 858f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 859f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 860f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh/* Initialize the list of open file descriptors with the file descriptors 861f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh we inherited from out parent process. */ 862f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 8631aa40211ec688cb47df0341e770fb59e933d5b5csewardjvoid VG_(init_preopened_fds)(void) 864f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 865f76d27a697a7b0bf3b84490baf60623fc96a23afnjn// DDD: should probably use HAVE_PROC here or similar, instead. 86681b975ce84471039f9d668274fd544419541ebabnjn#if defined(VGO_linux) 8670a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj Int ret; 868495c6563114d60a67caa5824a03dc4892cc86adbmjw struct vki_dirent64 d; 8699264559eba4aa5d397a278b4e1a50c03de30693fsewardj SysRes f; 870f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 871f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0); 872cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(f)) { 87381b975ce84471039f9d668274fd544419541ebabnjn init_preopened_fds_without_proc_self_fd(); 874f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh return; 875f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 876f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 877495c6563114d60a67caa5824a03dc4892cc86adbmjw while ((ret = VG_(getdents64)(sr_Res(f), &d, sizeof(d))) != 0) { 878f845f8ffb1d2fac86714e32f4e279700b07722dfnjn if (ret == -1) 879f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh goto out; 880f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 881f845f8ffb1d2fac86714e32f4e279700b07722dfnjn if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) { 88219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* s; 88383df0b67a14425c484d8dda42b53f3ff0b598894njn Int fno = VG_(strtoll10)(d.d_name, &s); 88483df0b67a14425c484d8dda42b53f3ff0b598894njn if (*s == '\0') { 885cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (fno != sr_Res(f)) 88683df0b67a14425c484d8dda42b53f3ff0b598894njn if (VG_(clo_track_fds)) 88783df0b67a14425c484d8dda42b53f3ff0b598894njn ML_(record_fd_open_named)(-1, fno); 88883df0b67a14425c484d8dda42b53f3ff0b598894njn } else { 88983df0b67a14425c484d8dda42b53f3ff0b598894njn VG_(message)(Vg_DebugMsg, 890738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Warning: invalid file name in /proc/self/fd: %s\n", 891738856f99eea33d86ce91dcb1d6cd5b151e307casewardj d.d_name); 89283df0b67a14425c484d8dda42b53f3ff0b598894njn } 893f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 894f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 895cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(lseek)(sr_Res(f), d.d_off, VKI_SEEK_SET); 896f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 897f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 8989264559eba4aa5d397a278b4e1a50c03de30693fsewardj out: 899cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(close)(sr_Res(f)); 90081b975ce84471039f9d668274fd544419541ebabnjn 901f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 902f76d27a697a7b0bf3b84490baf60623fc96a23afnjn init_preopened_fds_without_proc_self_fd(); 903f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 90481b975ce84471039f9d668274fd544419541ebabnjn#else 90581b975ce84471039f9d668274fd544419541ebabnjn# error Unknown OS 90681b975ce84471039f9d668274fd544419541ebabnjn#endif 907f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 908f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 909de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 910e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianHChar *strdupcat ( const HChar* cc, const HChar *s1, const HChar *s2, 911e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian ArenaId aid ) 912de4a1d01951937632098a6cda45859afa587a06fsewardj{ 913de4a1d01951937632098a6cda45859afa587a06fsewardj UInt len = VG_(strlen) ( s1 ) + VG_(strlen) ( s2 ) + 1; 914e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian HChar *result = VG_(arena_malloc) ( aid, cc, len ); 915de4a1d01951937632098a6cda45859afa587a06fsewardj VG_(strcpy) ( result, s1 ); 916de4a1d01951937632098a6cda45859afa587a06fsewardj VG_(strcat) ( result, s2 ); 917de4a1d01951937632098a6cda45859afa587a06fsewardj return result; 918de4a1d01951937632098a6cda45859afa587a06fsewardj} 919de4a1d01951937632098a6cda45859afa587a06fsewardj 920de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 92156e1c849d0f28d66b58843d8c3463c0d2e8409eatomvoid pre_mem_read_sendmsg ( ThreadId tid, Bool read, 922e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar *msg, Addr base, SizeT size ) 923de4a1d01951937632098a6cda45859afa587a06fsewardj{ 924e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian HChar *outmsg = strdupcat ( "di.syswrap.pmrs.1", 925e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian "sendmsg", msg, VG_AR_CORE ); 926ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( outmsg, base, size ); 92777eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(free) ( outmsg ); 928de4a1d01951937632098a6cda45859afa587a06fsewardj} 929de4a1d01951937632098a6cda45859afa587a06fsewardj 930de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 93156e1c849d0f28d66b58843d8c3463c0d2e8409eatomvoid pre_mem_write_recvmsg ( ThreadId tid, Bool read, 932e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar *msg, Addr base, SizeT size ) 933de4a1d01951937632098a6cda45859afa587a06fsewardj{ 934e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian HChar *outmsg = strdupcat ( "di.syswrap.pmwr.1", 935e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian "recvmsg", msg, VG_AR_CORE ); 93656e1c849d0f28d66b58843d8c3463c0d2e8409eatom if ( read ) 93756e1c849d0f28d66b58843d8c3463c0d2e8409eatom PRE_MEM_READ( outmsg, base, size ); 93856e1c849d0f28d66b58843d8c3463c0d2e8409eatom else 93956e1c849d0f28d66b58843d8c3463c0d2e8409eatom PRE_MEM_WRITE( outmsg, base, size ); 94077eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(free) ( outmsg ); 941de4a1d01951937632098a6cda45859afa587a06fsewardj} 942de4a1d01951937632098a6cda45859afa587a06fsewardj 943de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 94456e1c849d0f28d66b58843d8c3463c0d2e8409eatomvoid post_mem_write_recvmsg ( ThreadId tid, Bool read, 945e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar *fieldName, Addr base, SizeT size ) 946de4a1d01951937632098a6cda45859afa587a06fsewardj{ 94756e1c849d0f28d66b58843d8c3463c0d2e8409eatom if ( !read ) 94856e1c849d0f28d66b58843d8c3463c0d2e8409eatom POST_MEM_WRITE( base, size ); 949de4a1d01951937632098a6cda45859afa587a06fsewardj} 950de4a1d01951937632098a6cda45859afa587a06fsewardj 951de4a1d01951937632098a6cda45859afa587a06fsewardjstatic 9528c824516728858da07809e6023ebb0fe4118b629sewardjvoid msghdr_foreachfield ( 953a4991237861dd834a58620b6a9eeca0e6e843f24tom ThreadId tid, 954e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar *name, 9558b3a6094d817ca6677592ce7f1147eb24c1a94f4tom struct vki_msghdr *msg, 9568b3a6094d817ca6677592ce7f1147eb24c1a94f4tom UInt length, 957fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom void (*foreach_func)( ThreadId, Bool, const HChar *, Addr, SizeT ), 9586822be8ce58da00ecf03ec28ed6e81c8f283ed68sewardj Bool rekv /* "recv" apparently shadows some header decl on OSX108 */ 9598c824516728858da07809e6023ebb0fe4118b629sewardj ) 960de4a1d01951937632098a6cda45859afa587a06fsewardj{ 961e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian HChar *fieldName; 962a4991237861dd834a58620b6a9eeca0e6e843f24tom 963de4a1d01951937632098a6cda45859afa587a06fsewardj if ( !msg ) 964de4a1d01951937632098a6cda45859afa587a06fsewardj return; 965de4a1d01951937632098a6cda45859afa587a06fsewardj 96677eb20b3865e7b17c7695c7e7a526b52935f593eflorian fieldName = VG_(malloc) ( "di.syswrap.mfef", VG_(strlen)(name) + 32 ); 967a4991237861dd834a58620b6a9eeca0e6e843f24tom 968a4991237861dd834a58620b6a9eeca0e6e843f24tom VG_(sprintf) ( fieldName, "(%s)", name ); 969a4991237861dd834a58620b6a9eeca0e6e843f24tom 970a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, (Addr)&msg->msg_name, sizeof( msg->msg_name ) ); 971a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, (Addr)&msg->msg_namelen, sizeof( msg->msg_namelen ) ); 972a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, (Addr)&msg->msg_iov, sizeof( msg->msg_iov ) ); 973a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, (Addr)&msg->msg_iovlen, sizeof( msg->msg_iovlen ) ); 974a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, (Addr)&msg->msg_control, sizeof( msg->msg_control ) ); 975a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, (Addr)&msg->msg_controllen, sizeof( msg->msg_controllen ) ); 976fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom 977fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom /* msg_flags is completely ignored for send_mesg, recv_mesg doesn't read 978fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom the field, but does write to it. */ 9796822be8ce58da00ecf03ec28ed6e81c8f283ed68sewardj if ( rekv ) 980fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom foreach_func ( tid, False, fieldName, (Addr)&msg->msg_flags, sizeof( msg->msg_flags ) ); 981a4991237861dd834a58620b6a9eeca0e6e843f24tom 982aa02f66b9fd8cc55f28f37d97e04a3ebb025382bmjw if ( ML_(safe_to_deref)(&msg->msg_name, sizeof (void *)) 983aa02f66b9fd8cc55f28f37d97e04a3ebb025382bmjw && msg->msg_name ) { 984a4991237861dd834a58620b6a9eeca0e6e843f24tom VG_(sprintf) ( fieldName, "(%s.msg_name)", name ); 985a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, False, fieldName, 986de4a1d01951937632098a6cda45859afa587a06fsewardj (Addr)msg->msg_name, msg->msg_namelen ); 987a4991237861dd834a58620b6a9eeca0e6e843f24tom } 988de4a1d01951937632098a6cda45859afa587a06fsewardj 989aa02f66b9fd8cc55f28f37d97e04a3ebb025382bmjw if ( ML_(safe_to_deref)(&msg->msg_iov, sizeof (void *)) 990aa02f66b9fd8cc55f28f37d97e04a3ebb025382bmjw && msg->msg_iov ) { 99173b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_iovec *iov = msg->msg_iov; 992de4a1d01951937632098a6cda45859afa587a06fsewardj UInt i; 993de4a1d01951937632098a6cda45859afa587a06fsewardj 994a4991237861dd834a58620b6a9eeca0e6e843f24tom VG_(sprintf) ( fieldName, "(%s.msg_iov)", name ); 995a4991237861dd834a58620b6a9eeca0e6e843f24tom 996a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, True, fieldName, 99773b526fb4af0f60634f0078583d92b931d5c0eebnethercote (Addr)iov, msg->msg_iovlen * sizeof( struct vki_iovec ) ); 998de4a1d01951937632098a6cda45859afa587a06fsewardj 999a4991237861dd834a58620b6a9eeca0e6e843f24tom for ( i = 0; i < msg->msg_iovlen; ++i, ++iov ) { 10008b3a6094d817ca6677592ce7f1147eb24c1a94f4tom UInt iov_len = iov->iov_len <= length ? iov->iov_len : length; 1001a4991237861dd834a58620b6a9eeca0e6e843f24tom VG_(sprintf) ( fieldName, "(%s.msg_iov[%u])", name, i ); 1002a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, False, fieldName, 10038b3a6094d817ca6677592ce7f1147eb24c1a94f4tom (Addr)iov->iov_base, iov_len ); 10048b3a6094d817ca6677592ce7f1147eb24c1a94f4tom length = length - iov_len; 1005a4991237861dd834a58620b6a9eeca0e6e843f24tom } 1006de4a1d01951937632098a6cda45859afa587a06fsewardj } 1007de4a1d01951937632098a6cda45859afa587a06fsewardj 1008aa02f66b9fd8cc55f28f37d97e04a3ebb025382bmjw if ( ML_(safe_to_deref) (&msg->msg_control, sizeof (void *)) 1009aa02f66b9fd8cc55f28f37d97e04a3ebb025382bmjw && msg->msg_control ) 1010a4991237861dd834a58620b6a9eeca0e6e843f24tom { 1011a4991237861dd834a58620b6a9eeca0e6e843f24tom VG_(sprintf) ( fieldName, "(%s.msg_control)", name ); 1012a4991237861dd834a58620b6a9eeca0e6e843f24tom foreach_func ( tid, False, fieldName, 1013de4a1d01951937632098a6cda45859afa587a06fsewardj (Addr)msg->msg_control, msg->msg_controllen ); 1014a4991237861dd834a58620b6a9eeca0e6e843f24tom } 1015a4991237861dd834a58620b6a9eeca0e6e843f24tom 101677eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(free) ( fieldName ); 1017de4a1d01951937632098a6cda45859afa587a06fsewardj} 1018de4a1d01951937632098a6cda45859afa587a06fsewardj 1019b5f6f51ebcac183818061bf53427a3e7808ef10dsewardjstatic void check_cmsg_for_fds(ThreadId tid, struct vki_msghdr *msg) 1020f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 102173b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_cmsghdr *cm = VKI_CMSG_FIRSTHDR(msg); 1022f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 1023f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh while (cm) { 102473b526fb4af0f60634f0078583d92b931d5c0eebnethercote if (cm->cmsg_level == VKI_SOL_SOCKET && 102573b526fb4af0f60634f0078583d92b931d5c0eebnethercote cm->cmsg_type == VKI_SCM_RIGHTS ) { 10260a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj Int *fds = (Int *) VKI_CMSG_DATA(cm); 10270a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj Int fdc = (cm->cmsg_len - VKI_CMSG_ALIGN(sizeof(struct vki_cmsghdr))) 1028f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh / sizeof(int); 10290a400c7a4f8c6b5e9d431a453703096fbb2c076bsewardj Int i; 1030f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 1031f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh for (i = 0; i < fdc; i++) 1032f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh if(VG_(clo_track_fds)) 1033493dd18a6344fcb2a017a7b888d33b7fbe8b1519nethercote // XXX: must we check the range on these fds with 10347b2c38c2ed00b4214d199184a50837a009e1acc0cerion // ML_(fd_allowed)()? 1035096ccdd670d4e4eabdafb18598b1cd06d790fda8njn ML_(record_fd_open_named)(tid, fds[i]); 1036f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 1037f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 103873b526fb4af0f60634f0078583d92b931d5c0eebnethercote cm = VKI_CMSG_NXTHDR(msg, cm); 1039f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } 1040f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 1041f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh 1042f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* GrP kernel ignores sa_len (at least on Darwin); this checks the rest */ 1043c483e8fb94d84a57ac6df5e18f38465134d215bdsewardjstatic 1044855d93d2e9940890b28874520fa4c1677bf825e2jsgfvoid pre_mem_read_sockaddr ( ThreadId tid, 1045e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar *description, 1046a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj struct vki_sockaddr *sa, UInt salen ) 1047c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj{ 1048e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian HChar *outmsg; 1049ff42447f71582b9b56370f81cfe6c62811a57897njn struct vki_sockaddr_un* sun = (struct vki_sockaddr_un *)sa; 1050ff42447f71582b9b56370f81cfe6c62811a57897njn struct vki_sockaddr_in* sin = (struct vki_sockaddr_in *)sa; 1051ff42447f71582b9b56370f81cfe6c62811a57897njn struct vki_sockaddr_in6* sin6 = (struct vki_sockaddr_in6 *)sa; 105219ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# ifdef VKI_AF_BLUETOOTH 1053ada5ad79e5d8ecf47838319a46ea4671079e6291mjw struct vki_sockaddr_rc* rc = (struct vki_sockaddr_rc *)sa; 105419ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# endif 105519ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# ifdef VKI_AF_NETLINK 105619ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj struct vki_sockaddr_nl* nl = (struct vki_sockaddr_nl *)sa; 105719ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# endif 1058ff7c1ab3c10c5a7cf2aacb554f76fc1e40bf1901sewardj 1059ff7c1ab3c10c5a7cf2aacb554f76fc1e40bf1901sewardj /* NULL/zero-length sockaddrs are legal */ 1060ff7c1ab3c10c5a7cf2aacb554f76fc1e40bf1901sewardj if ( sa == NULL || salen == 0 ) return; 1061ff7c1ab3c10c5a7cf2aacb554f76fc1e40bf1901sewardj 106277eb20b3865e7b17c7695c7e7a526b52935f593eflorian outmsg = VG_(malloc) ( "di.syswrap.pmr_sockaddr.1", 106377eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(strlen)( description ) + 30 ); 1064c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj 1065ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sa_family" ); 1066ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( outmsg, (Addr) &sa->sa_family, sizeof(vki_sa_family_t)); 1067855d93d2e9940890b28874520fa4c1677bf825e2jsgf 1068c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj switch (sa->sa_family) { 1069c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj 107073b526fb4af0f60634f0078583d92b931d5c0eebnethercote case VKI_AF_UNIX: 1071ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sun_path" ); 1072ff42447f71582b9b56370f81cfe6c62811a57897njn PRE_MEM_RASCIIZ( outmsg, (Addr) sun->sun_path ); 1073f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // GrP fixme max of sun_len-2? what about nul char? 1074c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj break; 1075c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj 107673b526fb4af0f60634f0078583d92b931d5c0eebnethercote case VKI_AF_INET: 1077ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sin_port" ); 1078ff42447f71582b9b56370f81cfe6c62811a57897njn PRE_MEM_READ( outmsg, (Addr) &sin->sin_port, sizeof (sin->sin_port) ); 1079ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sin_addr" ); 1080ff42447f71582b9b56370f81cfe6c62811a57897njn PRE_MEM_READ( outmsg, (Addr) &sin->sin_addr, sizeof (sin->sin_addr) ); 1081c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj break; 1082c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj 108373b526fb4af0f60634f0078583d92b931d5c0eebnethercote case VKI_AF_INET6: 1084ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sin6_port" ); 1085ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( outmsg, 1086ff42447f71582b9b56370f81cfe6c62811a57897njn (Addr) &sin6->sin6_port, sizeof (sin6->sin6_port) ); 1087ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sin6_flowinfo" ); 1088ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( outmsg, 1089ff42447f71582b9b56370f81cfe6c62811a57897njn (Addr) &sin6->sin6_flowinfo, sizeof (sin6->sin6_flowinfo) ); 1090ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sin6_addr" ); 1091ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( outmsg, 1092ff42447f71582b9b56370f81cfe6c62811a57897njn (Addr) &sin6->sin6_addr, sizeof (sin6->sin6_addr) ); 1093ff42447f71582b9b56370f81cfe6c62811a57897njn VG_(sprintf) ( outmsg, description, "sin6_scope_id" ); 1094ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( outmsg, 1095ff42447f71582b9b56370f81cfe6c62811a57897njn (Addr) &sin6->sin6_scope_id, sizeof (sin6->sin6_scope_id) ); 1096c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj break; 10974cb663fdaa2a63efc447f7251270446c4e8c9611mjw 109819ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# ifdef VKI_AF_BLUETOOTH 1099ada5ad79e5d8ecf47838319a46ea4671079e6291mjw case VKI_AF_BLUETOOTH: 1100ada5ad79e5d8ecf47838319a46ea4671079e6291mjw VG_(sprintf) ( outmsg, description, "rc_bdaddr" ); 1101ada5ad79e5d8ecf47838319a46ea4671079e6291mjw PRE_MEM_READ( outmsg, (Addr) &rc->rc_bdaddr, sizeof (rc->rc_bdaddr) ); 1102ada5ad79e5d8ecf47838319a46ea4671079e6291mjw VG_(sprintf) ( outmsg, description, "rc_channel" ); 1103ada5ad79e5d8ecf47838319a46ea4671079e6291mjw PRE_MEM_READ( outmsg, (Addr) &rc->rc_channel, sizeof (rc->rc_channel) ); 1104ada5ad79e5d8ecf47838319a46ea4671079e6291mjw break; 110519ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# endif 110619ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj 110719ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# ifdef VKI_AF_NETLINK 110819ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj case VKI_AF_NETLINK: 110919ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj VG_(sprintf)(outmsg, description, "nl_pid"); 111019ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj PRE_MEM_READ(outmsg, (Addr)&nl->nl_pid, sizeof(nl->nl_pid)); 111119ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj VG_(sprintf)(outmsg, description, "nl_groups"); 111219ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj PRE_MEM_READ(outmsg, (Addr)&nl->nl_groups, sizeof(nl->nl_groups)); 111319ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj break; 111419ce5d572999bbccb6e380cf8bafb50d880c91f4sewardj# endif 1115ada5ad79e5d8ecf47838319a46ea4671079e6291mjw 1116aa62d8484d5414a997c06a06ca3d03ab69855a60sewardj# ifdef VKI_AF_UNSPEC 1117aa62d8484d5414a997c06a06ca3d03ab69855a60sewardj case VKI_AF_UNSPEC: 1118aa62d8484d5414a997c06a06ca3d03ab69855a60sewardj break; 1119aa62d8484d5414a997c06a06ca3d03ab69855a60sewardj# endif 1120aa62d8484d5414a997c06a06ca3d03ab69855a60sewardj 1121c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj default: 1122c06f684badc0701961e68dbc206fbf1757f7fd68philippe /* No specific information about this address family. 1123c06f684badc0701961e68dbc206fbf1757f7fd68philippe Let's just check the full data following the family. 1124c06f684badc0701961e68dbc206fbf1757f7fd68philippe Note that this can give false positive if this (unknown) 1125c06f684badc0701961e68dbc206fbf1757f7fd68philippe struct sockaddr_???? has padding bytes between its elements. */ 1126c06f684badc0701961e68dbc206fbf1757f7fd68philippe VG_(sprintf) ( outmsg, description, "sa_data" ); 1127c06f684badc0701961e68dbc206fbf1757f7fd68philippe PRE_MEM_READ( outmsg, (Addr)&sa->sa_family + sizeof(sa->sa_family), 112890a707399e43f1d8dfd0b8a4539d3beb7ec20420philippe salen - sizeof(sa->sa_family)); 1129c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj break; 1130c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj } 1131c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj 113277eb20b3865e7b17c7695c7e7a526b52935f593eflorian VG_(free) ( outmsg ); 1133c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj} 1134c483e8fb94d84a57ac6df5e18f38465134d215bdsewardj 1135e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* Dereference a pointer to a UInt. */ 1136e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianstatic UInt deref_UInt ( ThreadId tid, Addr a, const HChar* s ) 1137e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 1138e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn UInt* a_p = (UInt*)a; 1139ef0c7663cb71101c7b718108253444cb75402cbbnethercote PRE_MEM_READ( s, (Addr)a_p, sizeof(UInt) ); 1140e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn if (a_p == NULL) 1141e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn return 0; 1142e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn else 1143e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn return *a_p; 1144e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1145de4a1d01951937632098a6cda45859afa587a06fsewardj 1146f37a81bac9893b05fdb7166be94734babc7ad2c4njnvoid ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p, 1147e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian const HChar* buf_s, const HChar* buflen_s ) 1148e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 114951d827bcd88ce045a383ea1ca81768757df2d1fanjn if (VG_(tdict).track_pre_mem_write) { 115072718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s); 1151e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn if (buflen_in > 0) { 1152cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(tdict).track_pre_mem_write( 1153cda2f0fbda4c4b2644babc830244be8aed95de1dnjn Vg_CoreSysCall, tid, buf_s, buf_p, buflen_in ); 1154e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 1155e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 1156e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1157de4a1d01951937632098a6cda45859afa587a06fsewardj 1158f37a81bac9893b05fdb7166be94734babc7ad2c4njnvoid ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res, 1159e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian Addr buf_p, Addr buflen_p, const HChar* s ) 1160e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{ 1161cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!sr_isError(res) && VG_(tdict).track_post_mem_write) { 116272718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn UInt buflen_out = deref_UInt( tid, buflen_p, s); 1163e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn if (buflen_out > 0 && buf_p != (Addr)NULL) { 116451d827bcd88ce045a383ea1ca81768757df2d1fanjn VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out ); 1165e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 1166e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn } 1167e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn} 1168de4a1d01951937632098a6cda45859afa587a06fsewardj 1169e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* --------------------------------------------------------------------- 1170e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn Data seg end, for brk() 1171e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn ------------------------------------------------------------------ */ 11722e93c50dc50235189661b70e3f27a4098d5cccccsewardj 117345f4e7c91119c7d01a59f5e827c67841632c9314sewardj/* +--------+------------+ 117445f4e7c91119c7d01a59f5e827c67841632c9314sewardj | anon | resvn | 117545f4e7c91119c7d01a59f5e827c67841632c9314sewardj +--------+------------+ 117645f4e7c91119c7d01a59f5e827c67841632c9314sewardj 117745f4e7c91119c7d01a59f5e827c67841632c9314sewardj ^ ^ ^ 117845f4e7c91119c7d01a59f5e827c67841632c9314sewardj | | boundary is page aligned 117945f4e7c91119c7d01a59f5e827c67841632c9314sewardj | VG_(brk_limit) -- no alignment constraint 118045f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(brk_base) -- page aligned -- does not move 118145f4e7c91119c7d01a59f5e827c67841632c9314sewardj 118245f4e7c91119c7d01a59f5e827c67841632c9314sewardj Both the anon part and the reservation part are always at least 118345f4e7c91119c7d01a59f5e827c67841632c9314sewardj one page. 118445f4e7c91119c7d01a59f5e827c67841632c9314sewardj*/ 1185ce47126a7eb32765c5700c8adc3f5958aabc6394nethercote 118645f4e7c91119c7d01a59f5e827c67841632c9314sewardj/* Set the new data segment end to NEWBRK. If this succeeds, return 118745f4e7c91119c7d01a59f5e827c67841632c9314sewardj NEWBRK, else return the current data segment end. */ 118845f4e7c91119c7d01a59f5e827c67841632c9314sewardj 1189981abb5e4a0f43049ed7efac90cfa52ac61b5140florianstatic Addr do_brk ( Addr newbrk, ThreadId tid ) 119045f4e7c91119c7d01a59f5e827c67841632c9314sewardj{ 1191ef1cf8b3583107c7d918c60895937f09969d5b3esewardj NSegment const* aseg; 119245f4e7c91119c7d01a59f5e827c67841632c9314sewardj Addr newbrkP; 119345f4e7c91119c7d01a59f5e827c67841632c9314sewardj SizeT delta; 119445f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool debug = False; 119598abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 119698abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge if (debug) 1197a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("\ndo_brk: brk_base=%#lx brk_limit=%#lx newbrk=%#lx\n", 119898abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge VG_(brk_base), VG_(brk_limit), newbrk); 119998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 120095f1037b50883fa81420116d7a694be0099ab015florian if (0) VG_(am_show_nsegments)(0, "in_brk"); 1201548be6d64c58729588a559b1512ad7625bc1b86esewardj 120245f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (newbrk < VG_(brk_base)) 120345f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* Clearly impossible. */ 120445f4e7c91119c7d01a59f5e827c67841632c9314sewardj goto bad; 120545f4e7c91119c7d01a59f5e827c67841632c9314sewardj 120695f1037b50883fa81420116d7a694be0099ab015florian if (newbrk < VG_(brk_limit)) { 120745f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* shrinking the data segment. Be lazy and don't munmap the 120845f4e7c91119c7d01a59f5e827c67841632c9314sewardj excess area. */ 1209ef1cf8b3583107c7d918c60895937f09969d5b3esewardj NSegment const * seg = VG_(am_find_nsegment)(newbrk); 121095f1037b50883fa81420116d7a694be0099ab015florian vg_assert(seg); 121195f1037b50883fa81420116d7a694be0099ab015florian 121295f1037b50883fa81420116d7a694be0099ab015florian if (seg->hasT) 121345f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk, 121445f4e7c91119c7d01a59f5e827c67841632c9314sewardj "do_brk(shrink)" ); 1215d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj /* Since we're being lazy and not unmapping pages, we have to 1216d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj zero out the area, so that if the area later comes back into 1217d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj circulation, it will be filled with zeroes, as if it really 1218d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj had been unmapped and later remapped. Be a bit paranoid and 1219d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj try hard to ensure we're not going to segfault by doing the 1220d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj write - check both ends of the range are in the same segment 1221d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj and that segment is writable. */ 122295f1037b50883fa81420116d7a694be0099ab015florian NSegment const * seg2; 122395f1037b50883fa81420116d7a694be0099ab015florian 1224e787fcafaaa6bb8e794b27522f2038a3e128164cflorian seg2 = VG_(am_find_nsegment)( VG_(brk_limit) - 1 ); 122595f1037b50883fa81420116d7a694be0099ab015florian vg_assert(seg2); 122695f1037b50883fa81420116d7a694be0099ab015florian 122795f1037b50883fa81420116d7a694be0099ab015florian if (seg == seg2 && seg->hasW) 122895f1037b50883fa81420116d7a694be0099ab015florian VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk ); 1229d2d241b62cf81f3f0c2dbd14190a24f25c17e50fsewardj 123045f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(brk_limit) = newbrk; 123145f4e7c91119c7d01a59f5e827c67841632c9314sewardj return newbrk; 123245f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 123398abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 123445f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* otherwise we're expanding the brk segment. */ 12358e5963ddf24d3164b7de52f73fff090d9fc72d6atom if (VG_(brk_limit) > VG_(brk_base)) 12368e5963ddf24d3164b7de52f73fff090d9fc72d6atom aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 ); 12378e5963ddf24d3164b7de52f73fff090d9fc72d6atom else 12388e5963ddf24d3164b7de52f73fff090d9fc72d6atom aseg = VG_(am_find_nsegment)( VG_(brk_limit) ); 123945f4e7c91119c7d01a59f5e827c67841632c9314sewardj 124045f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* These should be assured by setup_client_dataseg in m_main. */ 124145f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(aseg); 124245f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(aseg->kind == SkAnonC); 124345f4e7c91119c7d01a59f5e827c67841632c9314sewardj 124495f1037b50883fa81420116d7a694be0099ab015florian if (newbrk <= aseg->end + 1) { 124545f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* still fits within the anon segment. */ 124645f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(brk_limit) = newbrk; 124745f4e7c91119c7d01a59f5e827c67841632c9314sewardj return newbrk; 124845f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 124998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 125045f4e7c91119c7d01a59f5e827c67841632c9314sewardj newbrkP = VG_PGROUNDUP(newbrk); 125195f1037b50883fa81420116d7a694be0099ab015florian delta = newbrkP - (aseg->end + 1); 125245f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(delta > 0); 125345f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(VG_IS_PAGE_ALIGNED(delta)); 125445f4e7c91119c7d01a59f5e827c67841632c9314sewardj 1255981abb5e4a0f43049ed7efac90cfa52ac61b5140florian Bool overflow; 125615fa8a2f9b64e24c76ef88d8bf660ea2296f0c36florian if (! VG_(am_extend_into_adjacent_reservation_client)( aseg->start, delta, 1257981abb5e4a0f43049ed7efac90cfa52ac61b5140florian &overflow)) { 1258981abb5e4a0f43049ed7efac90cfa52ac61b5140florian if (overflow) 1259981abb5e4a0f43049ed7efac90cfa52ac61b5140florian VG_(umsg)("brk segment overflow in thread #%d: can't grow to %#lx\n", 1260981abb5e4a0f43049ed7efac90cfa52ac61b5140florian tid, newbrkP); 1261981abb5e4a0f43049ed7efac90cfa52ac61b5140florian else 1262981abb5e4a0f43049ed7efac90cfa52ac61b5140florian VG_(umsg)("Cannot map memory to grow brk segment in thread #%d " 1263981abb5e4a0f43049ed7efac90cfa52ac61b5140florian "to %#lx\n", tid, newbrkP); 1264888b8159535580b30550f99cb7361f62edd83100florian goto bad; 1265981abb5e4a0f43049ed7efac90cfa52ac61b5140florian } 126698abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 126745f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(brk_limit) = newbrk; 126845f4e7c91119c7d01a59f5e827c67841632c9314sewardj return newbrk; 126998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 127045f4e7c91119c7d01a59f5e827c67841632c9314sewardj bad: 127145f4e7c91119c7d01a59f5e827c67841632c9314sewardj return VG_(brk_limit); 127298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge} 1273e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn 127498abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 1275e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* --------------------------------------------------------------------- 1276855d93d2e9940890b28874520fa4c1677bf825e2jsgf Vet file descriptors for sanity 1277e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn ------------------------------------------------------------------ */ 127804236905926acaf6288177f23d75c85a7540120esewardj/* 127904236905926acaf6288177f23d75c85a7540120esewardj> - what does the "Bool soft" parameter mean? 128004236905926acaf6288177f23d75c85a7540120esewardj 128104236905926acaf6288177f23d75c85a7540120esewardj(Tom Hughes, 3 Oct 05): 128204236905926acaf6288177f23d75c85a7540120esewardj 128304236905926acaf6288177f23d75c85a7540120esewardjWhether or not to consider a file descriptor invalid if it is above 128404236905926acaf6288177f23d75c85a7540120esewardjthe current soft limit. 128504236905926acaf6288177f23d75c85a7540120esewardj 128604236905926acaf6288177f23d75c85a7540120esewardjBasically if we are testing whether a newly created file descriptor is 128704236905926acaf6288177f23d75c85a7540120esewardjvalid (in a post handler) then we set soft to true, and if we are 128804236905926acaf6288177f23d75c85a7540120esewardjtesting whether a file descriptor that is about to be used (in a pre 128904236905926acaf6288177f23d75c85a7540120esewardjhandler) is valid [viz, an already-existing fd] then we set it to false. 129004236905926acaf6288177f23d75c85a7540120esewardj 129104236905926acaf6288177f23d75c85a7540120esewardjThe point is that if the (virtual) soft limit is lowered then any 129204236905926acaf6288177f23d75c85a7540120esewardjexisting descriptors can still be read/written/closed etc (so long as 129304236905926acaf6288177f23d75c85a7540120esewardjthey are below the valgrind reserved descriptors) but no new 129404236905926acaf6288177f23d75c85a7540120esewardjdescriptors can be created above the new soft limit. 129504236905926acaf6288177f23d75c85a7540120esewardj 129604236905926acaf6288177f23d75c85a7540120esewardj(jrs 4 Oct 05: in which case, I've renamed it "isNewFd") 129704236905926acaf6288177f23d75c85a7540120esewardj*/ 1298de4a1d01951937632098a6cda45859afa587a06fsewardj 1299855d93d2e9940890b28874520fa4c1677bf825e2jsgf/* Return true if we're allowed to use or create this fd */ 1300e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianBool ML_(fd_allowed)(Int fd, const HChar *syscallname, ThreadId tid, 1301e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian Bool isNewFd) 1302de4a1d01951937632098a6cda45859afa587a06fsewardj{ 130304236905926acaf6288177f23d75c85a7540120esewardj Bool allowed = True; 130404236905926acaf6288177f23d75c85a7540120esewardj 130504236905926acaf6288177f23d75c85a7540120esewardj /* hard limits always apply */ 130604236905926acaf6288177f23d75c85a7540120esewardj if (fd < 0 || fd >= VG_(fd_hard_limit)) 130704236905926acaf6288177f23d75c85a7540120esewardj allowed = False; 130804236905926acaf6288177f23d75c85a7540120esewardj 1309738856f99eea33d86ce91dcb1d6cd5b151e307casewardj /* hijacking the output fds is never allowed */ 1310738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (fd == VG_(log_output_sink).fd || fd == VG_(xml_output_sink).fd) 131104236905926acaf6288177f23d75c85a7540120esewardj allowed = False; 131204236905926acaf6288177f23d75c85a7540120esewardj 131304236905926acaf6288177f23d75c85a7540120esewardj /* if creating a new fd (rather than using an existing one), the 131404236905926acaf6288177f23d75c85a7540120esewardj soft limit must also be observed */ 131504236905926acaf6288177f23d75c85a7540120esewardj if (isNewFd && fd >= VG_(fd_soft_limit)) 131604236905926acaf6288177f23d75c85a7540120esewardj allowed = False; 131704236905926acaf6288177f23d75c85a7540120esewardj 131804236905926acaf6288177f23d75c85a7540120esewardj /* this looks like it ought to be included, but causes problems: */ 131904236905926acaf6288177f23d75c85a7540120esewardj /* 132004236905926acaf6288177f23d75c85a7540120esewardj if (fd == 2 && VG_(debugLog_getLevel)() > 0) 132104236905926acaf6288177f23d75c85a7540120esewardj allowed = False; 132204236905926acaf6288177f23d75c85a7540120esewardj */ 132304236905926acaf6288177f23d75c85a7540120esewardj /* The difficulty is as follows: consider a program P which expects 132404236905926acaf6288177f23d75c85a7540120esewardj to be able to mess with (redirect) its own stderr (fd 2). 132504236905926acaf6288177f23d75c85a7540120esewardj Usually to deal with P we would issue command line flags to send 132604236905926acaf6288177f23d75c85a7540120esewardj logging somewhere other than stderr, so as not to disrupt P. 132704236905926acaf6288177f23d75c85a7540120esewardj The problem is that -d unilaterally hijacks stderr with no 132804236905926acaf6288177f23d75c85a7540120esewardj consultation with P. And so, if this check is enabled, P will 132904236905926acaf6288177f23d75c85a7540120esewardj work OK normally but fail if -d is issued. 133004236905926acaf6288177f23d75c85a7540120esewardj 133104236905926acaf6288177f23d75c85a7540120esewardj Basically -d is a hack and you take your chances when using it. 133204236905926acaf6288177f23d75c85a7540120esewardj It's very useful for low level debugging -- particularly at 133304236905926acaf6288177f23d75c85a7540120esewardj startup -- and having its presence change the behaviour of the 133404236905926acaf6288177f23d75c85a7540120esewardj client is exactly what we don't want. */ 133504236905926acaf6288177f23d75c85a7540120esewardj 133604236905926acaf6288177f23d75c85a7540120esewardj /* croak? */ 133704236905926acaf6288177f23d75c85a7540120esewardj if ((!allowed) && VG_(showing_core_errors)() ) { 1338d9320a4a43b89ef5fc3b81a308816884ce92c0e9jseward VG_(message)(Vg_UserMsg, 1339738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Warning: invalid file descriptor %d in syscall %s()\n", 13401543adfbbb9bf65687148d2c8d5dd7e883dd7769nethercote fd, syscallname); 1341738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (fd == VG_(log_output_sink).fd && VG_(log_output_sink).fd >= 0) 1342d9320a4a43b89ef5fc3b81a308816884ce92c0e9jseward VG_(message)(Vg_UserMsg, 1343738856f99eea33d86ce91dcb1d6cd5b151e307casewardj " Use --log-fd=<number> to select an alternative log fd.\n"); 1344738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (fd == VG_(xml_output_sink).fd && VG_(xml_output_sink).fd >= 0) 1345738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, 1346738856f99eea33d86ce91dcb1d6cd5b151e307casewardj " Use --xml-fd=<number> to select an alternative XML " 1347738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "output fd.\n"); 1348eb04c8904805cd38872b0ca3134254570c943a30njn // DDD: consider always printing this stack trace, it's useful. 1349eb04c8904805cd38872b0ca3134254570c943a30njn // Also consider also making this a proper core error, ie. 1350eb04c8904805cd38872b0ca3134254570c943a30njn // suppressible and all that. 1351855d93d2e9940890b28874520fa4c1677bf825e2jsgf if (VG_(clo_verbosity) > 1) { 1352d01fef7de693582a6ce32bdbef7c9040ad6b356bnjn VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 1353855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 13541075931fcc5bf309074e478ac8369873a5a51bbesewardj } 135504236905926acaf6288177f23d75c85a7540120esewardj 135604236905926acaf6288177f23d75c85a7540120esewardj return allowed; 1357855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 1358de4a1d01951937632098a6cda45859afa587a06fsewardj 1359de4a1d01951937632098a6cda45859afa587a06fsewardj 1360855d93d2e9940890b28874520fa4c1677bf825e2jsgf/* --------------------------------------------------------------------- 13619efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Deal with a bunch of socket-related syscalls 13629efbbef43ba82de66e77c16a9319915b7346a5d3sewardj ------------------------------------------------------------------ */ 13639efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 13649efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 13659efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1366987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 13677eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_socketpair) ( ThreadId tid, 13689efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, 13699efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg2, UWord arg3 ) 13709efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 13719efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int socketpair(int d, int type, int protocol, int sv[2]); */ 13729efbbef43ba82de66e77c16a9319915b7346a5d3sewardj PRE_MEM_WRITE( "socketcall.socketpair(sv)", 13739efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg3, 2*sizeof(int) ); 13749efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 13759efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1376a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjSysRes 13777eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_socketpair) ( ThreadId tid, 1378a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes res, 1379987a8eb9731107bdb52e7747c2b5c516a5199beasewardj UWord arg0, UWord arg1, 1380987a8eb9731107bdb52e7747c2b5c516a5199beasewardj UWord arg2, UWord arg3 ) 13819efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 1382a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes r = res; 13839efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Int fd1 = ((Int*)arg3)[0]; 13849efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Int fd2 = ((Int*)arg3)[1]; 1385cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); /* guaranteed by caller */ 13869efbbef43ba82de66e77c16a9319915b7346a5d3sewardj POST_MEM_WRITE( arg3, 2*sizeof(int) ); 13877eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(fd1, "socketcall.socketpair", tid, True) || 13887eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj !ML_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) { 13899efbbef43ba82de66e77c16a9319915b7346a5d3sewardj VG_(close)(fd1); 13909efbbef43ba82de66e77c16a9319915b7346a5d3sewardj VG_(close)(fd2); 1391a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj r = VG_(mk_SysRes_Error)( VKI_EMFILE ); 13929efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } else { 13939efbbef43ba82de66e77c16a9319915b7346a5d3sewardj POST_MEM_WRITE( arg3, 2*sizeof(int) ); 13949efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (VG_(clo_track_fds)) { 1395f845f8ffb1d2fac86714e32f4e279700b07722dfnjn ML_(record_fd_open_nameless)(tid, fd1); 1396f845f8ffb1d2fac86714e32f4e279700b07722dfnjn ML_(record_fd_open_nameless)(tid, fd2); 13979efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } 13989efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } 13999efbbef43ba82de66e77c16a9319915b7346a5d3sewardj return r; 14009efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 14019efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 14029efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 14039efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1404a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjSysRes 14057eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_socket) ( ThreadId tid, SysRes res ) 14069efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 1407a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes r = res; 1408cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); /* guaranteed by caller */ 1409cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!ML_(fd_allowed)(sr_Res(res), "socket", tid, True)) { 1410cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(close)(sr_Res(res)); 1411a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj r = VG_(mk_SysRes_Error)( VKI_EMFILE ); 14129efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } else { 14139efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (VG_(clo_track_fds)) 1414cda2f0fbda4c4b2644babc830244be8aed95de1dnjn ML_(record_fd_open_nameless)(tid, sr_Res(res)); 14159efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } 14169efbbef43ba82de66e77c16a9319915b7346a5d3sewardj return r; 14179efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 14189efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 14199efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 14209efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1421987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 14227eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_bind) ( ThreadId tid, 14239efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 14249efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 14259efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int bind(int sockfd, struct sockaddr *my_addr, 14269efbbef43ba82de66e77c16a9319915b7346a5d3sewardj int addrlen); */ 14279efbbef43ba82de66e77c16a9319915b7346a5d3sewardj pre_mem_read_sockaddr( 14289efbbef43ba82de66e77c16a9319915b7346a5d3sewardj tid, "socketcall.bind(my_addr.%s)", 14299efbbef43ba82de66e77c16a9319915b7346a5d3sewardj (struct vki_sockaddr *) arg1, arg2 14309efbbef43ba82de66e77c16a9319915b7346a5d3sewardj ); 14319efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 14329efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 14339efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 14349efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1435987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 14367eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_accept) ( ThreadId tid, 14379efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 14389efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 14399efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int accept(int s, struct sockaddr *addr, int *addrlen); */ 14409efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr addr_p = arg1; 14419efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr addrlen_p = arg2; 14429efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (addr_p != (Addr)NULL) 1443f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_pre_check) ( tid, addr_p, addrlen_p, 1444f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.accept(addr)", 1445f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.accept(addrlen_in)" ); 14469efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 14479efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1448a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjSysRes 14497eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_accept) ( ThreadId tid, 1450a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes res, 1451987a8eb9731107bdb52e7747c2b5c516a5199beasewardj UWord arg0, UWord arg1, UWord arg2 ) 14529efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 1453a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes r = res; 1454cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); /* guaranteed by caller */ 1455cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!ML_(fd_allowed)(sr_Res(res), "accept", tid, True)) { 1456cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(close)(sr_Res(res)); 1457a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj r = VG_(mk_SysRes_Error)( VKI_EMFILE ); 14589efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } else { 14599efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr addr_p = arg1; 14609efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr addrlen_p = arg2; 14619efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (addr_p != (Addr)NULL) 1462f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_post_check) ( tid, res, addr_p, addrlen_p, 1463f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.accept(addrlen_out)" ); 14649efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (VG_(clo_track_fds)) 1465cda2f0fbda4c4b2644babc830244be8aed95de1dnjn ML_(record_fd_open_nameless)(tid, sr_Res(res)); 14669efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } 14679efbbef43ba82de66e77c16a9319915b7346a5d3sewardj return r; 14689efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 14699efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 14709efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 14719efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1472987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 14737eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_sendto) ( ThreadId tid, 14749efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2, 14759efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg3, UWord arg4, UWord arg5 ) 14769efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 14779efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int sendto(int s, const void *msg, int len, 14789efbbef43ba82de66e77c16a9319915b7346a5d3sewardj unsigned int flags, 14799efbbef43ba82de66e77c16a9319915b7346a5d3sewardj const struct sockaddr *to, int tolen); */ 14809efbbef43ba82de66e77c16a9319915b7346a5d3sewardj PRE_MEM_READ( "socketcall.sendto(msg)", 14819efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg1, /* msg */ 14829efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg2 /* len */ ); 14839efbbef43ba82de66e77c16a9319915b7346a5d3sewardj pre_mem_read_sockaddr( 14849efbbef43ba82de66e77c16a9319915b7346a5d3sewardj tid, "socketcall.sendto(to.%s)", 14859efbbef43ba82de66e77c16a9319915b7346a5d3sewardj (struct vki_sockaddr *) arg4, arg5 14869efbbef43ba82de66e77c16a9319915b7346a5d3sewardj ); 14879efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 14889efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 14899efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 14909efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1491987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 14927eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_send) ( ThreadId tid, 14939efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 14949efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 14959efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int send(int s, const void *msg, size_t len, int flags); */ 14969efbbef43ba82de66e77c16a9319915b7346a5d3sewardj PRE_MEM_READ( "socketcall.send(msg)", 14979efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg1, /* msg */ 14989efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg2 /* len */ ); 14999efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 15009efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15019efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 15029efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 15039efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1504987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15057eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_recvfrom) ( ThreadId tid, 15069efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2, 15079efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg3, UWord arg4, UWord arg5 ) 15089efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 15099efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int recvfrom(int s, void *buf, int len, unsigned int flags, 15109efbbef43ba82de66e77c16a9319915b7346a5d3sewardj struct sockaddr *from, int *fromlen); */ 15119efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr buf_p = arg1; 15129efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Int len = arg2; 15139efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr from_p = arg4; 15149efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr fromlen_p = arg5; 15159efbbef43ba82de66e77c16a9319915b7346a5d3sewardj PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len ); 15169efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (from_p != (Addr)NULL) 1517f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_pre_check) ( tid, from_p, fromlen_p, 1518f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.recvfrom(from)", 1519f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.recvfrom(fromlen_in)" ); 15209efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15219efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1522987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15237eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_recvfrom) ( ThreadId tid, 1524a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes res, 15259efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2, 15269efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg3, UWord arg4, UWord arg5 ) 15279efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 15289efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr buf_p = arg1; 15299efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Int len = arg2; 15309efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr from_p = arg4; 15319efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr fromlen_p = arg5; 15329efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1533cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); /* guaranteed by caller */ 15349efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (from_p != (Addr)NULL) 1535f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_post_check) ( tid, res, from_p, fromlen_p, 1536f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.recvfrom(fromlen_out)" ); 15379efbbef43ba82de66e77c16a9319915b7346a5d3sewardj POST_MEM_WRITE( buf_p, len ); 15389efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15399efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 15409efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 15419efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1542987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15437eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_recv) ( ThreadId tid, 15449efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 15459efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 15469efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int recv(int s, void *buf, int len, unsigned int flags); */ 15479efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* man 2 recv says: 15489efbbef43ba82de66e77c16a9319915b7346a5d3sewardj The recv call is normally used only on a connected socket 15499efbbef43ba82de66e77c16a9319915b7346a5d3sewardj (see connect(2)) and is identical to recvfrom with a NULL 15509efbbef43ba82de66e77c16a9319915b7346a5d3sewardj from parameter. 15519efbbef43ba82de66e77c16a9319915b7346a5d3sewardj */ 15529efbbef43ba82de66e77c16a9319915b7346a5d3sewardj PRE_MEM_WRITE( "socketcall.recv(buf)", 15539efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg1, /* buf */ 15549efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg2 /* len */ ); 15559efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15569efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1557987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15587eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_recv) ( ThreadId tid, 15599efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord res, 15609efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 15619efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 15629efbbef43ba82de66e77c16a9319915b7346a5d3sewardj if (res >= 0 && arg1 != 0) { 15639efbbef43ba82de66e77c16a9319915b7346a5d3sewardj POST_MEM_WRITE( arg1, /* buf */ 15649efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg2 /* len */ ); 15659efbbef43ba82de66e77c16a9319915b7346a5d3sewardj } 15669efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15679efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 15689efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 15699efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1570987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15717eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_connect) ( ThreadId tid, 15729efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 15739efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 15749efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int connect(int sockfd, 15759efbbef43ba82de66e77c16a9319915b7346a5d3sewardj struct sockaddr *serv_addr, int addrlen ); */ 15769efbbef43ba82de66e77c16a9319915b7346a5d3sewardj pre_mem_read_sockaddr( tid, 15779efbbef43ba82de66e77c16a9319915b7346a5d3sewardj "socketcall.connect(serv_addr.%s)", 15789efbbef43ba82de66e77c16a9319915b7346a5d3sewardj (struct vki_sockaddr *) arg1, arg2); 15799efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15809efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 15819efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 15829efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1583987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15847eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_setsockopt) ( ThreadId tid, 15859efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2, 15869efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg3, UWord arg4 ) 15879efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 15889efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int setsockopt(int s, int level, int optname, 15899efbbef43ba82de66e77c16a9319915b7346a5d3sewardj const void *optval, int optlen); */ 15909efbbef43ba82de66e77c16a9319915b7346a5d3sewardj PRE_MEM_READ( "socketcall.setsockopt(optval)", 15919efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg3, /* optval */ 15929efbbef43ba82de66e77c16a9319915b7346a5d3sewardj arg4 /* optlen */ ); 15939efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 15949efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 15959efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 15969efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1597987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 15987eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_getsockname) ( ThreadId tid, 15999efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 16009efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 16019efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int getsockname(int s, struct sockaddr* name, int* namelen) */ 16029efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr name_p = arg1; 16039efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr namelen_p = arg2; 16049efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* Nb: name_p cannot be NULL */ 1605f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p, 1606f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.getsockname(name)", 1607f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.getsockname(namelen_in)" ); 16089efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16099efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1610987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 16117eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_getsockname) ( ThreadId tid, 1612a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes res, 16139efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 16149efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 16159efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr name_p = arg1; 16169efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr namelen_p = arg2; 1617cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); /* guaranteed by caller */ 1618f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p, 1619f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.getsockname(namelen_out)" ); 16209efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16219efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 16229efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 16239efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1624987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 16257eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_getpeername) ( ThreadId tid, 16269efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 16279efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 16289efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* int getpeername(int s, struct sockaddr* name, int* namelen) */ 16299efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr name_p = arg1; 16309efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr namelen_p = arg2; 16319efbbef43ba82de66e77c16a9319915b7346a5d3sewardj /* Nb: name_p cannot be NULL */ 1632f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p, 1633f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.getpeername(name)", 1634f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.getpeername(namelen_in)" ); 16359efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16369efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1637987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 16387eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_getpeername) ( ThreadId tid, 1639a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes res, 16409efbbef43ba82de66e77c16a9319915b7346a5d3sewardj UWord arg0, UWord arg1, UWord arg2 ) 16419efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 16429efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr name_p = arg1; 16439efbbef43ba82de66e77c16a9319915b7346a5d3sewardj Addr namelen_p = arg2; 1644cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); /* guaranteed by caller */ 1645f37a81bac9893b05fdb7166be94734babc7ad2c4njn ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p, 1646f37a81bac9893b05fdb7166be94734babc7ad2c4njn "socketcall.getpeername(namelen_out)" ); 16479efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16489efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 16499efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 16509efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1651987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 1652e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianML_(generic_PRE_sys_sendmsg) ( ThreadId tid, const HChar *name, 1653e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian struct vki_msghdr *msg ) 16549efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 1655fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_read_sendmsg, False ); 16569efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16579efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 16589efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* ------ */ 16599efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1660987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 1661e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianML_(generic_PRE_sys_recvmsg) ( ThreadId tid, const HChar *name, 1662e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian struct vki_msghdr *msg ) 16639efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 1664fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom msghdr_foreachfield ( tid, name, msg, ~0, pre_mem_write_recvmsg, True ); 16659efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16669efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 1667987a8eb9731107bdb52e7747c2b5c516a5199beasewardjvoid 1668e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianML_(generic_POST_sys_recvmsg) ( ThreadId tid, const HChar *name, 1669e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian struct vki_msghdr *msg, UInt length ) 16709efbbef43ba82de66e77c16a9319915b7346a5d3sewardj{ 1671fc75e5ea3e57d58bbbbd3fd8fff3a71de9a1b172tom msghdr_foreachfield( tid, name, msg, length, post_mem_write_recvmsg, True ); 16729efbbef43ba82de66e77c16a9319915b7346a5d3sewardj check_cmsg_for_fds( tid, msg ); 16739efbbef43ba82de66e77c16a9319915b7346a5d3sewardj} 16749efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 16759efbbef43ba82de66e77c16a9319915b7346a5d3sewardj 16769efbbef43ba82de66e77c16a9319915b7346a5d3sewardj/* --------------------------------------------------------------------- 1677b369c5e35c69997f9bc5798f476108da59876cfcsewardj Deal with a bunch of IPC related syscalls 1678b369c5e35c69997f9bc5798f476108da59876cfcsewardj ------------------------------------------------------------------ */ 1679b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1680b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1681b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1682b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 16837eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_semop) ( ThreadId tid, 1684b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, UWord arg2 ) 1685b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1686b369c5e35c69997f9bc5798f476108da59876cfcsewardj /* int semop(int semid, struct sembuf *sops, unsigned nsops); */ 1687b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "semop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) ); 1688b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1689b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1690b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1691b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1692b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 16937eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_semtimedop) ( ThreadId tid, 1694b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, 1695b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg2, UWord arg3 ) 1696b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1697b369c5e35c69997f9bc5798f476108da59876cfcsewardj /* int semtimedop(int semid, struct sembuf *sops, unsigned nsops, 1698b369c5e35c69997f9bc5798f476108da59876cfcsewardj struct timespec *timeout); */ 1699b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "semtimedop(sops)", arg1, arg2 * sizeof(struct vki_sembuf) ); 1700b369c5e35c69997f9bc5798f476108da59876cfcsewardj if (arg3 != 0) 1701b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "semtimedop(timeout)", arg3, sizeof(struct vki_timespec) ); 1702b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1703b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1704b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1705b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1706b369c5e35c69997f9bc5798f476108da59876cfcsewardjstatic 1707b369c5e35c69997f9bc5798f476108da59876cfcsewardjUInt get_sem_count( Int semid ) 1708b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1709a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj struct vki_semid_ds buf; 1710a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj union vki_semun arg; 1711a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes res; 1712b369c5e35c69997f9bc5798f476108da59876cfcsewardj 171327f96b3cd47d996b344a02cc5b9adf03e6ea1b43sewardj /* Doesn't actually seem to be necessary, but gcc-4.4.0 20081017 171427f96b3cd47d996b344a02cc5b9adf03e6ea1b43sewardj (experimental) otherwise complains that the use in the return 171527f96b3cd47d996b344a02cc5b9adf03e6ea1b43sewardj statement below is uninitialised. */ 171627f96b3cd47d996b344a02cc5b9adf03e6ea1b43sewardj buf.sem_nsems = 0; 171727f96b3cd47d996b344a02cc5b9adf03e6ea1b43sewardj 1718a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj arg.buf = &buf; 1719b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1720a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj# ifdef __NR_semctl 1721a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg); 1722a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj# else 1723a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0, 1724a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VKI_IPC_STAT, (UWord)&arg); 172527f96b3cd47d996b344a02cc5b9adf03e6ea1b43sewardj# endif 1726cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(res)) 1727a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj return 0; 1728b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1729a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj return buf.sem_nsems; 1730b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1731b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1732b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 17337eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_semctl) ( ThreadId tid, 1734b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, 1735b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg2, UWord arg3 ) 1736b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1737b369c5e35c69997f9bc5798f476108da59876cfcsewardj /* int semctl(int semid, int semnum, int cmd, ...); */ 1738b369c5e35c69997f9bc5798f476108da59876cfcsewardj union vki_semun arg = *(union vki_semun *)&arg3; 1739b369c5e35c69997f9bc5798f476108da59876cfcsewardj UInt nsems; 1740b369c5e35c69997f9bc5798f476108da59876cfcsewardj switch (arg2 /* cmd */) { 1741f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_INFO) 1742b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO: 1743b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_INFO: 1744b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO|VKI_IPC_64: 1745b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_INFO|VKI_IPC_64: 1746b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "semctl(IPC_INFO, arg.buf)", 1747b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.buf, sizeof(struct vki_seminfo) ); 1748b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1749f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1750f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1751b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT: 1752f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SEM_STAT) 1753b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_STAT: 1754f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1755b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)", 1756b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.buf, sizeof(struct vki_semid_ds) ); 1757b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1758f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1759f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1760b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT|VKI_IPC_64: 1761f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SEM_STAT) 1762b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_STAT|VKI_IPC_64: 1763f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1764b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "semctl(IPC_STAT, arg.buf)", 1765b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.buf, sizeof(struct vki_semid64_ds) ); 1766b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1767f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1768f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1769b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_SET: 1770b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "semctl(IPC_SET, arg.buf)", 1771b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.buf, sizeof(struct vki_semid_ds) ); 1772b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1773f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1774f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1775b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_SET|VKI_IPC_64: 1776b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "semctl(IPC_SET, arg.buf)", 1777b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.buf, sizeof(struct vki_semid64_ds) ); 1778b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1779f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1780f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1781b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_GETALL: 1782f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1783b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_GETALL|VKI_IPC_64: 1784f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1785b369c5e35c69997f9bc5798f476108da59876cfcsewardj nsems = get_sem_count( arg0 ); 1786b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "semctl(IPC_GETALL, arg.array)", 1787b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.array, sizeof(unsigned short) * nsems ); 1788b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1789f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1790b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SETALL: 1791f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1792b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SETALL|VKI_IPC_64: 1793f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1794b369c5e35c69997f9bc5798f476108da59876cfcsewardj nsems = get_sem_count( arg0 ); 1795b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "semctl(IPC_SETALL, arg.array)", 1796b369c5e35c69997f9bc5798f476108da59876cfcsewardj (Addr)arg.array, sizeof(unsigned short) * nsems ); 1797b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1798b369c5e35c69997f9bc5798f476108da59876cfcsewardj } 1799b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1800b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1801b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 18027eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_semctl) ( ThreadId tid, 1803b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord res, 1804b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, 1805b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg2, UWord arg3 ) 1806b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1807b369c5e35c69997f9bc5798f476108da59876cfcsewardj union vki_semun arg = *(union vki_semun *)&arg3; 1808b369c5e35c69997f9bc5798f476108da59876cfcsewardj UInt nsems; 1809b369c5e35c69997f9bc5798f476108da59876cfcsewardj switch (arg2 /* cmd */) { 1810f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_INFO) 1811b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO: 1812b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_INFO: 1813b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO|VKI_IPC_64: 1814b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_INFO|VKI_IPC_64: 1815b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_seminfo) ); 1816b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1817f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1818f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1819b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT: 1820f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SEM_STAT) 1821b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_STAT: 1822f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1823b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid_ds) ); 1824b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1825f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1826f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1827b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT|VKI_IPC_64: 1828b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SEM_STAT|VKI_IPC_64: 1829b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( (Addr)arg.buf, sizeof(struct vki_semid64_ds) ); 1830b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1831f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1832f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1833b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_GETALL: 1834f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1835b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_GETALL|VKI_IPC_64: 1836f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1837b369c5e35c69997f9bc5798f476108da59876cfcsewardj nsems = get_sem_count( arg0 ); 1838b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( (Addr)arg.array, sizeof(unsigned short) * nsems ); 1839b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1840b369c5e35c69997f9bc5798f476108da59876cfcsewardj } 1841b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1842b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1843b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1844b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1845b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1846b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1847b369c5e35c69997f9bc5798f476108da59876cfcsewardjstatic 18482d75ea221634d6f74ab9e22be9e77370c33ce457philippeSizeT get_shm_size ( Int shmid ) 1849b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1850cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#ifdef __NR_shmctl 1851cda2f0fbda4c4b2644babc830244be8aed95de1dnjn# ifdef VKI_IPC_64 1852b369c5e35c69997f9bc5798f476108da59876cfcsewardj struct vki_shmid64_ds buf; 1853c8d064a1ea7d7855c5735a388f3ad47c44d4dcb7philippe# if defined(VGP_amd64_linux) || defined(VGP_arm64_linux) 185490741b2f5fba62332effcd9fb4c549905d909edbsewardj /* See bug 222545 comment 7 */ 185590741b2f5fba62332effcd9fb4c549905d909edbsewardj SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, 185690741b2f5fba62332effcd9fb4c549905d909edbsewardj VKI_IPC_STAT, (UWord)&buf); 185790741b2f5fba62332effcd9fb4c549905d909edbsewardj# else 185890741b2f5fba62332effcd9fb4c549905d909edbsewardj SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, 185990741b2f5fba62332effcd9fb4c549905d909edbsewardj VKI_IPC_STAT|VKI_IPC_64, (UWord)&buf); 186090741b2f5fba62332effcd9fb4c549905d909edbsewardj# endif 186190741b2f5fba62332effcd9fb4c549905d909edbsewardj# else /* !def VKI_IPC_64 */ 1862b369c5e35c69997f9bc5798f476108da59876cfcsewardj struct vki_shmid_ds buf; 1863cda2f0fbda4c4b2644babc830244be8aed95de1dnjn SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf); 186490741b2f5fba62332effcd9fb4c549905d909edbsewardj# endif /* def VKI_IPC_64 */ 1865cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#else 1866cda2f0fbda4c4b2644babc830244be8aed95de1dnjn struct vki_shmid_ds buf; 1867a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid, 1868b369c5e35c69997f9bc5798f476108da59876cfcsewardj VKI_IPC_STAT, 0, (UWord)&buf); 1869cda2f0fbda4c4b2644babc830244be8aed95de1dnjn#endif 1870cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(__res)) 1871b369c5e35c69997f9bc5798f476108da59876cfcsewardj return 0; 1872b369c5e35c69997f9bc5798f476108da59876cfcsewardj 18732d75ea221634d6f74ab9e22be9e77370c33ce457philippe return (SizeT) buf.shm_segsz; 1874b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1875b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1876b369c5e35c69997f9bc5798f476108da59876cfcsewardjUWord 18777eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_shmat) ( ThreadId tid, 1878b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, UWord arg2 ) 1879b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1880b369c5e35c69997f9bc5798f476108da59876cfcsewardj /* void *shmat(int shmid, const void *shmaddr, int shmflg); */ 18812d75ea221634d6f74ab9e22be9e77370c33ce457philippe SizeT segmentSize = get_shm_size ( arg0 ); 188245f4e7c91119c7d01a59f5e827c67841632c9314sewardj UWord tmp; 188345f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool ok; 188445f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (arg1 == 0) { 188560457093d30b23ac2531682205ab0bd9a5aae2edsewardj /* arm-linux only: work around the fact that 188660457093d30b23ac2531682205ab0bd9a5aae2edsewardj VG_(am_get_advisory_client_simple) produces something that is 188760457093d30b23ac2531682205ab0bd9a5aae2edsewardj VKI_PAGE_SIZE aligned, whereas what we want is something 188860457093d30b23ac2531682205ab0bd9a5aae2edsewardj VKI_SHMLBA aligned, and VKI_SHMLBA >= VKI_PAGE_SIZE. Hence 188960457093d30b23ac2531682205ab0bd9a5aae2edsewardj increase the request size by VKI_SHMLBA - VKI_PAGE_SIZE and 189060457093d30b23ac2531682205ab0bd9a5aae2edsewardj then round the result up to the next VKI_SHMLBA boundary. 189160457093d30b23ac2531682205ab0bd9a5aae2edsewardj See bug 222545 comment 15. So far, arm-linux is the only 189260457093d30b23ac2531682205ab0bd9a5aae2edsewardj platform where this is known to be necessary. */ 189360457093d30b23ac2531682205ab0bd9a5aae2edsewardj vg_assert(VKI_SHMLBA >= VKI_PAGE_SIZE); 189460457093d30b23ac2531682205ab0bd9a5aae2edsewardj if (VKI_SHMLBA > VKI_PAGE_SIZE) { 189560457093d30b23ac2531682205ab0bd9a5aae2edsewardj segmentSize += VKI_SHMLBA - VKI_PAGE_SIZE; 189660457093d30b23ac2531682205ab0bd9a5aae2edsewardj } 189745f4e7c91119c7d01a59f5e827c67841632c9314sewardj tmp = VG_(am_get_advisory_client_simple)(0, segmentSize, &ok); 189860457093d30b23ac2531682205ab0bd9a5aae2edsewardj if (ok) { 189960457093d30b23ac2531682205ab0bd9a5aae2edsewardj if (VKI_SHMLBA > VKI_PAGE_SIZE) { 190060457093d30b23ac2531682205ab0bd9a5aae2edsewardj arg1 = VG_ROUNDUP(tmp, VKI_SHMLBA); 190160457093d30b23ac2531682205ab0bd9a5aae2edsewardj } else { 190260457093d30b23ac2531682205ab0bd9a5aae2edsewardj arg1 = tmp; 190360457093d30b23ac2531682205ab0bd9a5aae2edsewardj } 190460457093d30b23ac2531682205ab0bd9a5aae2edsewardj } 190545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 19067eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj else if (!ML_(valid_client_addr)(arg1, segmentSize, tid, "shmat")) 1907b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg1 = 0; 1908b369c5e35c69997f9bc5798f476108da59876cfcsewardj return arg1; 1909b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1910b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1911b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 19127eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_shmat) ( ThreadId tid, 1913b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord res, 1914b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, UWord arg2 ) 1915b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 19162d75ea221634d6f74ab9e22be9e77370c33ce457philippe SizeT segmentSize = VG_PGROUNDUP(get_shm_size(arg0)); 1917b369c5e35c69997f9bc5798f476108da59876cfcsewardj if ( segmentSize > 0 ) { 1918b369c5e35c69997f9bc5798f476108da59876cfcsewardj UInt prot = VKI_PROT_READ|VKI_PROT_WRITE; 191945f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool d; 1920b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1921f61fea0d88fc6cc2a6c4ff78c49aa0343529ee20tom if (arg2 & VKI_SHM_RDONLY) 1922b369c5e35c69997f9bc5798f476108da59876cfcsewardj prot &= ~VKI_PROT_WRITE; 192345f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* It isn't exactly correct to pass 0 for the fd and offset 192445f4e7c91119c7d01a59f5e827c67841632c9314sewardj here. The kernel seems to think the corresponding section 192545f4e7c91119c7d01a59f5e827c67841632c9314sewardj does have dev/ino numbers: 192645f4e7c91119c7d01a59f5e827c67841632c9314sewardj 192745f4e7c91119c7d01a59f5e827c67841632c9314sewardj 04e52000-04ec8000 rw-s 00000000 00:06 1966090 /SYSV00000000 (deleted) 192845f4e7c91119c7d01a59f5e827c67841632c9314sewardj 192945f4e7c91119c7d01a59f5e827c67841632c9314sewardj However there is no obvious way to find them. In order to 193045f4e7c91119c7d01a59f5e827c67841632c9314sewardj cope with the discrepancy, aspacem's sync checker omits the 193145f4e7c91119c7d01a59f5e827c67841632c9314sewardj dev/ino correspondence check in cases where V does not know 193245f4e7c91119c7d01a59f5e827c67841632c9314sewardj the dev/ino. */ 1933c6fe8a25cbdc45c74d68a533c41b4e4ce2d8dec4njn d = VG_(am_notify_client_shmat)( res, segmentSize, prot ); 193445f4e7c91119c7d01a59f5e827c67841632c9314sewardj 193545f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* we don't distinguish whether it's read-only or 193645f4e7c91119c7d01a59f5e827c67841632c9314sewardj * read-write -- it doesn't matter really. */ 19379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False, 19389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj 0/*di_handle*/ ); 193945f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (d) 1940ddd61ff058f02059064e083a8accaefed23d5548florian VG_(discard_translations)( (Addr)res, 194145f4e7c91119c7d01a59f5e827c67841632c9314sewardj (ULong)VG_PGROUNDUP(segmentSize), 194245f4e7c91119c7d01a59f5e827c67841632c9314sewardj "ML_(generic_POST_sys_shmat)" ); 1943b369c5e35c69997f9bc5798f476108da59876cfcsewardj } 1944b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1945b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1946b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1947b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1948b369c5e35c69997f9bc5798f476108da59876cfcsewardjBool 19497eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_shmdt) ( ThreadId tid, UWord arg0 ) 1950b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1951b369c5e35c69997f9bc5798f476108da59876cfcsewardj /* int shmdt(const void *shmaddr); */ 19527eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj return ML_(valid_client_addr)(arg0, 1, tid, "shmdt"); 1953b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1954b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1955b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 19567eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 ) 1957b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1958ef1cf8b3583107c7d918c60895937f09969d5b3esewardj NSegment const* s = VG_(am_find_nsegment)(arg0); 195945f4e7c91119c7d01a59f5e827c67841632c9314sewardj 19600e682c673ffc284737fcd2610e2326fc08ac21fesewardj if (s != NULL) { 19610e682c673ffc284737fcd2610e2326fc08ac21fesewardj Addr s_start = s->start; 19620e682c673ffc284737fcd2610e2326fc08ac21fesewardj SizeT s_len = s->end+1 - s->start; 19631340c35bebb175c6d158361596ee6171b4cfc2a2tom Bool d; 19641340c35bebb175c6d158361596ee6171b4cfc2a2tom 19657bc57fc9c923e2630c42260d7142a5205a4bca66dirk vg_assert(s->kind == SkShmC); 19667bc57fc9c923e2630c42260d7142a5205a4bca66dirk vg_assert(s->start == arg0); 19671340c35bebb175c6d158361596ee6171b4cfc2a2tom 19681340c35bebb175c6d158361596ee6171b4cfc2a2tom d = VG_(am_notify_munmap)(s_start, s_len); 19690e682c673ffc284737fcd2610e2326fc08ac21fesewardj s = NULL; /* s is now invalid */ 19700e682c673ffc284737fcd2610e2326fc08ac21fesewardj VG_TRACK( die_mem_munmap, s_start, s_len ); 197145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (d) 1972ddd61ff058f02059064e083a8accaefed23d5548florian VG_(discard_translations)( s_start, 19730e682c673ffc284737fcd2610e2326fc08ac21fesewardj (ULong)s_len, 197445f4e7c91119c7d01a59f5e827c67841632c9314sewardj "ML_(generic_POST_sys_shmdt)" ); 1975b369c5e35c69997f9bc5798f476108da59876cfcsewardj } 1976b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 1977b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* ------ */ 1978b369c5e35c69997f9bc5798f476108da59876cfcsewardj 1979b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 19807eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_PRE_sys_shmctl) ( ThreadId tid, 1981b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, UWord arg2 ) 1982b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 1983b369c5e35c69997f9bc5798f476108da59876cfcsewardj /* int shmctl(int shmid, int cmd, struct shmid_ds *buf); */ 1984b369c5e35c69997f9bc5798f476108da59876cfcsewardj switch (arg1 /* cmd */) { 1985f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_INFO) 1986b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO: 1987b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", 1988b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shminfo) ); 1989b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1990f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 1991b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO|VKI_IPC_64: 1992b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "shmctl(IPC_INFO, buf)", 1993b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shminfo64) ); 1994b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 1995f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1996f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 1997f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 1998f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SHM_INFO) 1999b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_INFO: 2000f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 2001b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_INFO|VKI_IPC_64: 2002f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2003b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "shmctl(SHM_INFO, buf)", 2004b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shm_info) ); 2005b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2006f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2007f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2008b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT: 2009f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SHM_STAT) 2010b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_STAT: 2011f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2012b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "shmctl(IPC_STAT, buf)", 2013b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shmid_ds) ); 2014b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2015f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2016f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 2017b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT|VKI_IPC_64: 2018b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_STAT|VKI_IPC_64: 2019b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_WRITE( "shmctl(IPC_STAT, arg.buf)", 2020b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shmid64_ds) ); 2021b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2022f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2023f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2024b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_SET: 2025b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)", 2026b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shmid_ds) ); 2027b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2028f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2029f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 2030b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_SET|VKI_IPC_64: 2031b369c5e35c69997f9bc5798f476108da59876cfcsewardj PRE_MEM_READ( "shmctl(IPC_SET, arg.buf)", 2032b369c5e35c69997f9bc5798f476108da59876cfcsewardj arg2, sizeof(struct vki_shmid64_ds) ); 2033b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2034f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2035b369c5e35c69997f9bc5798f476108da59876cfcsewardj } 2036b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 2037b369c5e35c69997f9bc5798f476108da59876cfcsewardj 2038b369c5e35c69997f9bc5798f476108da59876cfcsewardjvoid 20397eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjML_(generic_POST_sys_shmctl) ( ThreadId tid, 2040b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord res, 2041b369c5e35c69997f9bc5798f476108da59876cfcsewardj UWord arg0, UWord arg1, UWord arg2 ) 2042b369c5e35c69997f9bc5798f476108da59876cfcsewardj{ 2043b369c5e35c69997f9bc5798f476108da59876cfcsewardj switch (arg1 /* cmd */) { 2044f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_INFO) 2045b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO: 2046b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo) ); 2047b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2048b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_INFO|VKI_IPC_64: 2049b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( arg2, sizeof(struct vki_shminfo64) ); 2050b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2051f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2052f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2053f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SHM_INFO) 2054b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_INFO: 2055b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_INFO|VKI_IPC_64: 2056b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( arg2, sizeof(struct vki_shm_info) ); 2057b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2058f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2059f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2060b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT: 2061f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_SHM_STAT) 2062b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_STAT: 2063f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2064b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( arg2, sizeof(struct vki_shmid_ds) ); 2065b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2066f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2067f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_IPC_64) 2068b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_IPC_STAT|VKI_IPC_64: 2069b369c5e35c69997f9bc5798f476108da59876cfcsewardj case VKI_SHM_STAT|VKI_IPC_64: 2070b369c5e35c69997f9bc5798f476108da59876cfcsewardj POST_MEM_WRITE( arg2, sizeof(struct vki_shmid64_ds) ); 2071b369c5e35c69997f9bc5798f476108da59876cfcsewardj break; 2072f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 2073f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2074f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2075b369c5e35c69997f9bc5798f476108da59876cfcsewardj } 2076b369c5e35c69997f9bc5798f476108da59876cfcsewardj} 2077b369c5e35c69997f9bc5798f476108da59876cfcsewardj 2078b369c5e35c69997f9bc5798f476108da59876cfcsewardj/* --------------------------------------------------------------------- 20799548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom Generic handler for mmap 20809548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom ------------------------------------------------------------------ */ 20819548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 20826d85b04b5c645991811b574af6633bf45106d43ctom/* 20836d85b04b5c645991811b574af6633bf45106d43ctom * Although mmap is specified by POSIX and the argument are generally 20846d85b04b5c645991811b574af6633bf45106d43ctom * consistent across platforms the precise details of the low level 20856d85b04b5c645991811b574af6633bf45106d43ctom * argument passing conventions differ. For example: 20866d85b04b5c645991811b574af6633bf45106d43ctom * 20876d85b04b5c645991811b574af6633bf45106d43ctom * - On x86-linux there is mmap (aka old_mmap) which takes the 20886d85b04b5c645991811b574af6633bf45106d43ctom * arguments in a memory block and the offset in bytes; and 20896d85b04b5c645991811b574af6633bf45106d43ctom * mmap2 (aka sys_mmap2) which takes the arguments in the normal 20906d85b04b5c645991811b574af6633bf45106d43ctom * way and the offset in pages. 20916d85b04b5c645991811b574af6633bf45106d43ctom * 20926d85b04b5c645991811b574af6633bf45106d43ctom * - On ppc32-linux there is mmap (aka sys_mmap) which takes the 20936d85b04b5c645991811b574af6633bf45106d43ctom * arguments in the normal way and the offset in bytes; and 20946d85b04b5c645991811b574af6633bf45106d43ctom * mmap2 (aka sys_mmap2) which takes the arguments in the normal 20956d85b04b5c645991811b574af6633bf45106d43ctom * way and the offset in pages. 20966d85b04b5c645991811b574af6633bf45106d43ctom * 20976d85b04b5c645991811b574af6633bf45106d43ctom * - On amd64-linux everything is simple and there is just the one 20986d85b04b5c645991811b574af6633bf45106d43ctom * call, mmap (aka sys_mmap) which takes the arguments in the 20996d85b04b5c645991811b574af6633bf45106d43ctom * normal way and the offset in bytes. 21006d85b04b5c645991811b574af6633bf45106d43ctom * 2101b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * - On s390x-linux there is mmap (aka old_mmap) which takes the 2102b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * arguments in a memory block and the offset in bytes. mmap2 2103b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * is also available (but not exported via unistd.h) with 2104b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * arguments in a memory block and the offset in pages. 2105b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj * 21066d85b04b5c645991811b574af6633bf45106d43ctom * To cope with all this we provide a generic handler function here 21076d85b04b5c645991811b574af6633bf45106d43ctom * and then each platform implements one or more system call handlers 21086d85b04b5c645991811b574af6633bf45106d43ctom * which call this generic routine after extracting and normalising 21096d85b04b5c645991811b574af6633bf45106d43ctom * the arguments. 21106d85b04b5c645991811b574af6633bf45106d43ctom */ 21116d85b04b5c645991811b574af6633bf45106d43ctom 21129548a16a2cf8a0de3f4d9d72e5777e9b70481f14tomSysRes 21139548a16a2cf8a0de3f4d9d72e5777e9b70481f14tomML_(generic_PRE_sys_mmap) ( ThreadId tid, 21149548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom UWord arg1, UWord arg2, UWord arg3, 2115274461dcb67f680196c97e8afb7028a79b97dcb7sewardj UWord arg4, UWord arg5, Off64T arg6 ) 21169548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom{ 21179548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom Addr advised; 21189548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom SysRes sres; 21199548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom MapRequest mreq; 21209548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom Bool mreq_ok; 21219548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 212280fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj# if defined(VGO_darwin) 2123f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // Nb: we can't use this on Darwin, it has races: 2124f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // * needs to RETRY if advisory succeeds but map fails 2125f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // (could have been some other thread in a nonblocking call) 2126f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // * needs to not use fixed-position mmap() on Darwin 2127f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // (mmap will cheerfully smash whatever's already there, which might 2128f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // be a new mapping from some other thread in a nonblocking call) 2129f76d27a697a7b0bf3b84490baf60623fc96a23afnjn VG_(core_panic)("can't use ML_(generic_PRE_sys_mmap) on Darwin"); 213080fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj# endif 2131f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 21329548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom if (arg2 == 0) { 21339548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* SuSV3 says: If len is zero, mmap() shall fail and no mapping 21349548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom shall be established. */ 21359548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom return VG_(mk_SysRes_Error)( VKI_EINVAL ); 21369548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } 21379548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 21389548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom if (!VG_IS_PAGE_ALIGNED(arg1)) { 21399548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* zap any misaligned addresses. */ 21409548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* SuSV3 says misaligned addresses only cause the MAP_FIXED case 21419548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom to fail. Here, we catch them all. */ 21429548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom return VG_(mk_SysRes_Error)( VKI_EINVAL ); 21439548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } 21449548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 21457e21df8076ae62b4921d2356d8aca0237c6910fdsewardj if (!VG_IS_PAGE_ALIGNED(arg6)) { 21467e21df8076ae62b4921d2356d8aca0237c6910fdsewardj /* zap any misaligned offsets. */ 21477e21df8076ae62b4921d2356d8aca0237c6910fdsewardj /* SuSV3 says: The off argument is constrained to be aligned and 21487e21df8076ae62b4921d2356d8aca0237c6910fdsewardj sized according to the value returned by sysconf() when 21497e21df8076ae62b4921d2356d8aca0237c6910fdsewardj passed _SC_PAGESIZE or _SC_PAGE_SIZE. */ 21507e21df8076ae62b4921d2356d8aca0237c6910fdsewardj return VG_(mk_SysRes_Error)( VKI_EINVAL ); 21517e21df8076ae62b4921d2356d8aca0237c6910fdsewardj } 21527e21df8076ae62b4921d2356d8aca0237c6910fdsewardj 215380fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj# if defined(VKI_MAP_32BIT) 215480fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj /* We can't support MAP_32BIT (at least, not without significant 215580fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj complication), and it's royally unportable, so if the client 215680fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj asks for it, just fail it. */ 215780fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj if (arg4 & VKI_MAP_32BIT) { 215880fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj return VG_(mk_SysRes_Error)( VKI_ENOMEM ); 215980fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj } 216080fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj# endif 216180fe549a7e8ed88f20ba0ab11832c441b6151fc0sewardj 21629548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* Figure out what kind of allocation constraints there are 21639548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom (fixed/hint/any), and ask aspacem what we should do. */ 21649548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom mreq.start = arg1; 21659548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom mreq.len = arg2; 21669548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom if (arg4 & VKI_MAP_FIXED) { 21679548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom mreq.rkind = MFixed; 21689548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } else 21699548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom if (arg1 != 0) { 21709548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom mreq.rkind = MHint; 21719548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } else { 21729548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom mreq.rkind = MAny; 21739548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } 21749548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 21759548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* Enquire ... */ 21769548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); 21779548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom if (!mreq_ok) { 21789548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* Our request was bounced, so we'd better fail. */ 21799548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom return VG_(mk_SysRes_Error)( VKI_EINVAL ); 21809548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } 21819548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 21829548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* Otherwise we're OK (so far). Install aspacem's choice of 21839548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom address, and let the mmap go through. */ 21849548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3, 21859548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom arg4 | VKI_MAP_FIXED, 21869548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom arg5, arg6); 21879548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 2188427d016169ed81e11686474acf76ba02c42eb977sewardj /* A refinement: it may be that the kernel refused aspacem's choice 2189427d016169ed81e11686474acf76ba02c42eb977sewardj of address. If we were originally asked for a hinted mapping, 2190427d016169ed81e11686474acf76ba02c42eb977sewardj there is still a last chance: try again at any address. 2191427d016169ed81e11686474acf76ba02c42eb977sewardj Hence: */ 2192cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (mreq.rkind == MHint && sr_isError(sres)) { 2193427d016169ed81e11686474acf76ba02c42eb977sewardj mreq.start = 0; 2194427d016169ed81e11686474acf76ba02c42eb977sewardj mreq.len = arg2; 2195427d016169ed81e11686474acf76ba02c42eb977sewardj mreq.rkind = MAny; 2196427d016169ed81e11686474acf76ba02c42eb977sewardj advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok ); 2197427d016169ed81e11686474acf76ba02c42eb977sewardj if (!mreq_ok) { 2198427d016169ed81e11686474acf76ba02c42eb977sewardj /* Our request was bounced, so we'd better fail. */ 2199427d016169ed81e11686474acf76ba02c42eb977sewardj return VG_(mk_SysRes_Error)( VKI_EINVAL ); 2200427d016169ed81e11686474acf76ba02c42eb977sewardj } 2201427d016169ed81e11686474acf76ba02c42eb977sewardj /* and try again with the kernel */ 2202427d016169ed81e11686474acf76ba02c42eb977sewardj sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3, 2203427d016169ed81e11686474acf76ba02c42eb977sewardj arg4 | VKI_MAP_FIXED, 2204427d016169ed81e11686474acf76ba02c42eb977sewardj arg5, arg6); 2205427d016169ed81e11686474acf76ba02c42eb977sewardj } 2206427d016169ed81e11686474acf76ba02c42eb977sewardj 220798d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe /* Yet another refinement : sometimes valgrind chooses an address 220898d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe which is not acceptable by the kernel. This at least happens 220998d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe when mmap-ing huge pages, using the flag MAP_HUGETLB. 221098d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe valgrind aspacem does not know about huge pages, and modifying 221198d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe it to handle huge pages is not straightforward (e.g. need 221298d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe to understand special file system mount options). 221398d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe So, let's just redo an mmap, without giving any constraint to 221498d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe the kernel. If that succeeds, check with aspacem that the returned 221598d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe address is acceptable (i.e. is free). 221698d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe This will give a similar effect as if the user would have 221798d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe specified a MAP_FIXED at that address. 221898d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe The aspacem state will be correctly updated afterwards. 221998d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe We however cannot do this last refinement when the user asked 222098d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe for a fixed mapping, as the user asked a specific address. */ 222198d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe if (sr_isError(sres) && !(arg4 & VKI_MAP_FIXED)) { 222298d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe advised = 0; 222398d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe /* try mmap with NULL address and without VKI_MAP_FIXED 222498d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe to let the kernel decide. */ 222598d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3, 222698d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe arg4, 222798d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe arg5, arg6); 222898d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe if (!sr_isError(sres)) { 222998d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe vg_assert(VG_(am_covered_by_single_free_segment)((Addr)sr_Res(sres), 223098d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe arg2)); 223198d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe } 223298d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe } 223398d6b25e8ce18fe287b1fc9d0c46e963d622cf3dphilippe 2234cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!sr_isError(sres)) { 22359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ULong di_handle; 2236510521e3ad8afb569be39ba46794dbe6e7b65a72bart /* Notify aspacem. */ 2237dd3725800151572d32df10ad4df4c8aad0d3d088njn notify_core_of_mmap( 2238cda2f0fbda4c4b2644babc830244be8aed95de1dnjn (Addr)sr_Res(sres), /* addr kernel actually assigned */ 2239510521e3ad8afb569be39ba46794dbe6e7b65a72bart arg2, /* length */ 2240510521e3ad8afb569be39ba46794dbe6e7b65a72bart arg3, /* prot */ 22419548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom arg4, /* the original flags value */ 2242510521e3ad8afb569be39ba46794dbe6e7b65a72bart arg5, /* fd */ 2243510521e3ad8afb569be39ba46794dbe6e7b65a72bart arg6 /* offset */ 22449548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom ); 22459548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* Load symbols? */ 2246cda2f0fbda4c4b2644babc830244be8aed95de1dnjn di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres), 22475f2dcad945d0bf3aaa9c9449ae90a5f2ca69adf1sewardj False/*allow_SkFileV*/, (Int)arg5 ); 2248510521e3ad8afb569be39ba46794dbe6e7b65a72bart /* Notify the tool. */ 2249510521e3ad8afb569be39ba46794dbe6e7b65a72bart notify_tool_of_mmap( 2250cda2f0fbda4c4b2644babc830244be8aed95de1dnjn (Addr)sr_Res(sres), /* addr kernel actually assigned */ 2251510521e3ad8afb569be39ba46794dbe6e7b65a72bart arg2, /* length */ 2252510521e3ad8afb569be39ba46794dbe6e7b65a72bart arg3, /* prot */ 22539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj di_handle /* so the tool can refer to the read debuginfo later, 22549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj if it wants. */ 2255510521e3ad8afb569be39ba46794dbe6e7b65a72bart ); 22569548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom } 22579548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 22589548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom /* Stay sane */ 2259cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED)) 2260cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(sr_Res(sres) == arg1); 22619548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 22629548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom return sres; 22639548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom} 22649548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 22659548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom 22669548a16a2cf8a0de3f4d9d72e5777e9b70481f14tom/* --------------------------------------------------------------------- 22674fa681f368f50057260d6a75ab2a04de4b8436b9nethercote The Main Entertainment ... syscall wrappers 2268855d93d2e9940890b28874520fa4c1677bf825e2jsgf ------------------------------------------------------------------ */ 2269de4a1d01951937632098a6cda45859afa587a06fsewardj 22704fa681f368f50057260d6a75ab2a04de4b8436b9nethercote/* Note: the PRE() and POST() wrappers are for the actual functions 22718ff888f31d22e31ce0370fe9205972b3b1f36e95nethercote implementing the system calls in the OS kernel. These mostly have 22724fa681f368f50057260d6a75ab2a04de4b8436b9nethercote names like sys_write(); a few have names like old_mmap(). See the 2273af839f52d74df156d655201a889954133ab01be7njn comment for ML_(syscall_table)[] for important info about the __NR_foo 22748ff888f31d22e31ce0370fe9205972b3b1f36e95nethercote constants and their relationship to the sys_foo() functions. 22754fa681f368f50057260d6a75ab2a04de4b8436b9nethercote 227692b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote Some notes about names used for syscalls and args: 227792b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote - For the --trace-syscalls=yes output, we use the sys_foo() name to avoid 227892b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote ambiguity. 227992b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote 228092b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote - For error messages, we generally use a somewhat generic name 228192b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote for the syscall (eg. "write" rather than "sys_write"). This should be 228292b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote good enough for the average user to understand what is happening, 228392b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote without confusing them with names like "sys_write". 228492b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote 228592b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote - Also, for error messages the arg names are mostly taken from the man 228692b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote pages (even though many of those man pages are really for glibc 22878ff888f31d22e31ce0370fe9205972b3b1f36e95nethercote functions of the same name), rather than from the OS kernel source, 228892b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote for the same reason -- a user presented with a "bogus foo(bar)" arg 228992b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote will most likely look at the "foo" man page to see which is the "bar" 229092b2fd542e89939b46edfa5c424af81f4a3bfe0cnethercote arg. 22918b76fe55a596a4296ba5028e2510015fef38b02fnethercote 22929c311eb3d0c532a972449e5e600d10f0470120b6nethercote Note that we use our own vki_* types. The one exception is in 22939c311eb3d0c532a972449e5e600d10f0470120b6nethercote PRE_REG_READn calls, where pointer types haven't been changed, because 22949c311eb3d0c532a972449e5e600d10f0470120b6nethercote they don't need to be -- eg. for "foo*" to be used, the type foo need not 22959c311eb3d0c532a972449e5e600d10f0470120b6nethercote be visible. 22969c311eb3d0c532a972449e5e600d10f0470120b6nethercote 22974fa681f368f50057260d6a75ab2a04de4b8436b9nethercote XXX: some of these are arch-specific, and should be factored out. 22984fa681f368f50057260d6a75ab2a04de4b8436b9nethercote*/ 22994fa681f368f50057260d6a75ab2a04de4b8436b9nethercote 2300a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj#define PRE(name) DEFN_PRE_TEMPLATE(generic, name) 2301a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj#define POST(name) DEFN_POST_TEMPLATE(generic, name) 2302ef0c7663cb71101c7b718108253444cb75402cbbnethercote 2303ca78724a71ba13f05b92455a8156206e6df27e56tom// Macros to support 64-bit syscall args split into two 32 bit values 2304ca78724a71ba13f05b92455a8156206e6df27e56tom#if defined(VG_LITTLEENDIAN) 2305ca78724a71ba13f05b92455a8156206e6df27e56tom#define MERGE64(lo,hi) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) ) 2306ca78724a71ba13f05b92455a8156206e6df27e56tom#define MERGE64_FIRST(name) name##_low 2307ca78724a71ba13f05b92455a8156206e6df27e56tom#define MERGE64_SECOND(name) name##_high 2308ca78724a71ba13f05b92455a8156206e6df27e56tom#elif defined(VG_BIGENDIAN) 2309ca78724a71ba13f05b92455a8156206e6df27e56tom#define MERGE64(hi,lo) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) ) 2310ca78724a71ba13f05b92455a8156206e6df27e56tom#define MERGE64_FIRST(name) name##_high 2311ca78724a71ba13f05b92455a8156206e6df27e56tom#define MERGE64_SECOND(name) name##_low 2312ca78724a71ba13f05b92455a8156206e6df27e56tom#else 2313ca78724a71ba13f05b92455a8156206e6df27e56tom#error Unknown endianness 231489d43f79c020c46b895e2ae916f61e2555636ec8njn#endif 2315e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj 2316a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_exit) 2317855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 2318a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ThreadState* tst; 2319a922b61f6014e389560475cb7886be77c3aa19f8sewardj /* simple; just make this thread exit */ 2320a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("exit( %ld )", ARG1); 2321aab814edf1195cbfbe0c75f2d66c0cbc8cc65a65njn PRE_REG_READ1(void, "exit", int, status); 2322a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj tst = VG_(get_ThreadState)(tid); 2323a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj /* Set the thread's status to be exiting, then claim that the 2324a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj syscall succeeded. */ 2325ef1cf8b3583107c7d918c60895937f09969d5b3esewardj tst->exitreason = VgSrc_ExitThread; 2326a922b61f6014e389560475cb7886be77c3aa19f8sewardj tst->os_state.exitcode = ARG1; 2327a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Success(0); 2328855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 2329be23ae7491ed887d2df349b3560b316dc871e59dsewardj 2330a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_ni_syscall) 2331eb1c7b730b5f601c2a5d55ee3dd02f930df4792fnethercote{ 23321a1e95c1f385a9b3b4f13f231eebaafff6e56450njn PRINT("unimplemented (by the kernel) syscall: %s! (ni_syscall)\n", 23331a1e95c1f385a9b3b4f13f231eebaafff6e56450njn VG_SYSNUM_STRING(SYSNO)); 2334eb1c7b730b5f601c2a5d55ee3dd02f930df4792fnethercote PRE_REG_READ0(long, "ni_syscall"); 2335a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_ENOSYS ); 2336a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj} 2337a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 2338696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_iopl) 2339696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2340a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_iopl ( %ld )", ARG1); 2341696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "iopl", unsigned long, level); 2342696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2343696c55180aae375b48f7acc3f2aa87e13040c807sewardj 234478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_fsync) 234578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 234678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj *flags |= SfMayBlock; 2347a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fsync ( %ld )", ARG1); 234878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ1(long, "fsync", unsigned int, fd); 234978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 235078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 2351696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_fdatasync) 2352696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2353696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 2354a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fdatasync ( %ld )", ARG1); 2355696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "fdatasync", unsigned int, fd); 2356696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2357696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2358696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_msync) 2359696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2360696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 2361a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_msync ( %#lx, %llu, %ld )", ARG1,(ULong)ARG2,ARG3); 2362696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ3(long, "msync", 2363696c55180aae375b48f7acc3f2aa87e13040c807sewardj unsigned long, start, vki_size_t, length, int, flags); 2364696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_READ( "msync(start)", ARG1, ARG2 ); 2365696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2366696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2367e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj// Nb: getpmsg() and putpmsg() are special additional syscalls used in early 2368e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj// versions of LiS (Linux Streams). They are not part of the kernel. 2369e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj// Therefore, we have to provide this type ourself, rather than getting it 2370e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj// from the kernel sources. 2371e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjstruct vki_pmsg_strbuf { 2372e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj int maxlen; /* no. of bytes in buffer */ 2373e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj int len; /* no. of bytes returned */ 2374e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj vki_caddr_t buf; /* pointer to data */ 2375e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj}; 2376e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_getpmsg) 2377e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 2378e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */ 2379e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj struct vki_pmsg_strbuf *ctrl; 2380e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj struct vki_pmsg_strbuf *data; 2381e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj *flags |= SfMayBlock; 2382a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getpmsg ( %ld, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5); 2383e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ5(int, "getpmsg", 2384e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj int, fd, struct strbuf *, ctrl, struct strbuf *, data, 2385e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj int *, bandp, int *, flagsp); 2386e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj ctrl = (struct vki_pmsg_strbuf *)ARG2; 2387e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj data = (struct vki_pmsg_strbuf *)ARG3; 2388e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (ctrl && ctrl->maxlen > 0) 2389e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen); 2390e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (data && data->maxlen > 0) 2391e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen); 2392e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (ARG4) 2393e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int)); 2394e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (ARG5) 2395e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int)); 2396e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 2397e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPOST(sys_getpmsg) 2398e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 2399e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj struct vki_pmsg_strbuf *ctrl; 2400e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj struct vki_pmsg_strbuf *data; 2401e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj vg_assert(SUCCESS); 2402e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj ctrl = (struct vki_pmsg_strbuf *)ARG2; 2403e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj data = (struct vki_pmsg_strbuf *)ARG3; 2404e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (RES == 0 && ctrl && ctrl->len > 0) { 2405e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len); 2406e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj } 2407e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (RES == 0 && data && data->len > 0) { 2408e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj POST_MEM_WRITE( (Addr)data->buf, data->len); 2409e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj } 2410e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 2411e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj 2412e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_putpmsg) 2413e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 2414e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */ 2415e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj struct vki_pmsg_strbuf *ctrl; 2416e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj struct vki_pmsg_strbuf *data; 2417e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj *flags |= SfMayBlock; 2418a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_putpmsg ( %ld, %#lx, %#lx, %ld, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5); 2419e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ5(int, "putpmsg", 2420e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj int, fd, struct strbuf *, ctrl, struct strbuf *, data, 2421e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj int, band, int, flags); 2422e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj ctrl = (struct vki_pmsg_strbuf *)ARG2; 2423e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj data = (struct vki_pmsg_strbuf *)ARG3; 2424e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (ctrl && ctrl->len > 0) 2425e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len); 2426e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (data && data->len > 0) 2427e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len); 2428e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 2429696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2430696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_getitimer) 2431696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 243272bbd8d24c6bd39734f465ce8d54904b6865de9bnjn struct vki_itimerval *value = (struct vki_itimerval*)ARG2; 2433a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getitimer ( %ld, %#lx )", ARG1, ARG2); 2434696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value); 243572bbd8d24c6bd39734f465ce8d54904b6865de9bnjn 243672bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_WRITE( "getitimer(&value->it_interval)", &(value->it_interval)); 243772bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_WRITE( "getitimer(&value->it_value)", &(value->it_value)); 2438696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2439f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 2440696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_getitimer) 2441696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2442696c55180aae375b48f7acc3f2aa87e13040c807sewardj if (ARG2 != (Addr)NULL) { 244372bbd8d24c6bd39734f465ce8d54904b6865de9bnjn struct vki_itimerval *value = (struct vki_itimerval*)ARG2; 244472bbd8d24c6bd39734f465ce8d54904b6865de9bnjn POST_timeval_WRITE( &(value->it_interval) ); 244572bbd8d24c6bd39734f465ce8d54904b6865de9bnjn POST_timeval_WRITE( &(value->it_value) ); 2446696c55180aae375b48f7acc3f2aa87e13040c807sewardj } 2447696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2448696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2449696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_setitimer) 2450696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2451a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setitimer ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3); 2452696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ3(long, "setitimer", 2453696c55180aae375b48f7acc3f2aa87e13040c807sewardj int, which, 2454696c55180aae375b48f7acc3f2aa87e13040c807sewardj struct itimerval *, value, struct itimerval *, ovalue); 245572bbd8d24c6bd39734f465ce8d54904b6865de9bnjn if (ARG2 != (Addr)NULL) { 245672bbd8d24c6bd39734f465ce8d54904b6865de9bnjn struct vki_itimerval *value = (struct vki_itimerval*)ARG2; 245772bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_READ( "setitimer(&value->it_interval)", 245872bbd8d24c6bd39734f465ce8d54904b6865de9bnjn &(value->it_interval)); 245972bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_READ( "setitimer(&value->it_value)", 246072bbd8d24c6bd39734f465ce8d54904b6865de9bnjn &(value->it_value)); 246172bbd8d24c6bd39734f465ce8d54904b6865de9bnjn } 246272bbd8d24c6bd39734f465ce8d54904b6865de9bnjn if (ARG3 != (Addr)NULL) { 246372bbd8d24c6bd39734f465ce8d54904b6865de9bnjn struct vki_itimerval *ovalue = (struct vki_itimerval*)ARG3; 246472bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_WRITE( "setitimer(&ovalue->it_interval)", 246572bbd8d24c6bd39734f465ce8d54904b6865de9bnjn &(ovalue->it_interval)); 246672bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_WRITE( "setitimer(&ovalue->it_value)", 246772bbd8d24c6bd39734f465ce8d54904b6865de9bnjn &(ovalue->it_value)); 246872bbd8d24c6bd39734f465ce8d54904b6865de9bnjn } 2469696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2470696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2471696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_setitimer) 2472696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2473696c55180aae375b48f7acc3f2aa87e13040c807sewardj if (ARG3 != (Addr)NULL) { 247472bbd8d24c6bd39734f465ce8d54904b6865de9bnjn struct vki_itimerval *ovalue = (struct vki_itimerval*)ARG3; 247572bbd8d24c6bd39734f465ce8d54904b6865de9bnjn POST_timeval_WRITE( &(ovalue->it_interval) ); 247672bbd8d24c6bd39734f465ce8d54904b6865de9bnjn POST_timeval_WRITE( &(ovalue->it_value) ); 2477696c55180aae375b48f7acc3f2aa87e13040c807sewardj } 2478696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2479696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2480696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_chroot) 2481696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2482a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_chroot ( %#lx )", ARG1); 2483696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "chroot", const char *, path); 2484696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_RASCIIZ( "chroot(path)", ARG1 ); 2485696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2486a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 2487a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_madvise) 2488a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj{ 2489a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 2490a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_madvise ( %#lx, %llu, %ld )", ARG1,(ULong)ARG2,ARG3); 2491a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_REG_READ3(long, "madvise", 2492a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj unsigned long, start, vki_size_t, length, int, advice); 24932e1c37dfb4583a40fa1e93bc4c7285c24d152b7fnethercote} 24942e1c37dfb4583a40fa1e93bc4c7285c24d152b7fnethercote 2495f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if HAVE_MREMAP 2496a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_mremap) 24972e1c37dfb4583a40fa1e93bc4c7285c24d152b7fnethercote{ 2498a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj // Nb: this is different to the glibc version described in the man pages, 2499a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj // which lacks the fifth 'new_address' argument. 2500c00fcc79fefd027c24f3a977013a97f7b13aa6catom if (ARG4 & VKI_MREMAP_FIXED) { 2501a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mremap ( %#lx, %llu, %ld, 0x%lx, %#lx )", 2502c00fcc79fefd027c24f3a977013a97f7b13aa6catom ARG1, (ULong)ARG2, ARG3, ARG4, ARG5); 2503c00fcc79fefd027c24f3a977013a97f7b13aa6catom PRE_REG_READ5(unsigned long, "mremap", 2504c00fcc79fefd027c24f3a977013a97f7b13aa6catom unsigned long, old_addr, unsigned long, old_size, 2505c00fcc79fefd027c24f3a977013a97f7b13aa6catom unsigned long, new_size, unsigned long, flags, 2506c00fcc79fefd027c24f3a977013a97f7b13aa6catom unsigned long, new_addr); 2507c00fcc79fefd027c24f3a977013a97f7b13aa6catom } else { 2508a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mremap ( %#lx, %llu, %ld, 0x%lx )", 2509c00fcc79fefd027c24f3a977013a97f7b13aa6catom ARG1, (ULong)ARG2, ARG3, ARG4); 2510c00fcc79fefd027c24f3a977013a97f7b13aa6catom PRE_REG_READ4(unsigned long, "mremap", 2511c00fcc79fefd027c24f3a977013a97f7b13aa6catom unsigned long, old_addr, unsigned long, old_size, 2512c00fcc79fefd027c24f3a977013a97f7b13aa6catom unsigned long, new_size, unsigned long, flags); 2513c00fcc79fefd027c24f3a977013a97f7b13aa6catom } 2514a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_from_SysRes( 251545f4e7c91119c7d01a59f5e827c67841632c9314sewardj do_mremap((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) 2516a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ); 2517855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 2518f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* HAVE_MREMAP */ 2519de4a1d01951937632098a6cda45859afa587a06fsewardj 25208c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardjPRE(sys_nice) 25218c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj{ 2522a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_nice ( %ld )", ARG1); 25238c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj PRE_REG_READ1(long, "nice", int, inc); 25248c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj} 252578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 2526696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_mlock) 2527696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2528696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 2529a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mlock ( %#lx, %llu )", ARG1, (ULong)ARG2); 2530696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len); 2531696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2532696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2533696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_munlock) 2534696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2535696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 2536a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_munlock ( %#lx, %llu )", ARG1, (ULong)ARG2); 2537696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len); 2538696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2539696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2540696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_mlockall) 2541696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2542696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 2543a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mlockall ( %lx )", ARG1); 2544696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "mlockall", int, flags); 2545696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2546696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2547696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_setpriority) 2548696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2549a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setpriority ( %ld, %ld, %ld )", ARG1, ARG2, ARG3); 2550696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio); 2551696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2552696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2553696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_getpriority) 2554696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2555a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getpriority ( %ld, %ld )", ARG1, ARG2); 2556696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "getpriority", int, which, int, who); 2557696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2558696c55180aae375b48f7acc3f2aa87e13040c807sewardj 25597b1edbdf64325be8000b0662a2f9695c0fa53465njnPRE(sys_pwrite64) 2560edc9547bf4ab4268fd2273ff91dde7f22ab692f8sewardj{ 2561e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj *flags |= SfMayBlock; 25627b1edbdf64325be8000b0662a2f9695c0fa53465njn#if VG_WORDSIZE == 4 2563a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_pwrite64 ( %ld, %#lx, %llu, %lld )", 2564ca78724a71ba13f05b92455a8156206e6df27e56tom ARG1, ARG2, (ULong)ARG3, MERGE64(ARG4,ARG5)); 2565e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ5(ssize_t, "pwrite64", 2566e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj unsigned int, fd, const char *, buf, vki_size_t, count, 25670ca89e0201db387d572047e9afb5d74786370208sewardj vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset)); 25687b1edbdf64325be8000b0662a2f9695c0fa53465njn#elif VG_WORDSIZE == 8 25697b1edbdf64325be8000b0662a2f9695c0fa53465njn PRINT("sys_pwrite64 ( %ld, %#lx, %llu, %lld )", 25707b1edbdf64325be8000b0662a2f9695c0fa53465njn ARG1, ARG2, (ULong)ARG3, (Long)ARG4); 25717b1edbdf64325be8000b0662a2f9695c0fa53465njn PRE_REG_READ4(ssize_t, "pwrite64", 25727b1edbdf64325be8000b0662a2f9695c0fa53465njn unsigned int, fd, const char *, buf, vki_size_t, count, 25737b1edbdf64325be8000b0662a2f9695c0fa53465njn Word, offset); 25747b1edbdf64325be8000b0662a2f9695c0fa53465njn#else 25757b1edbdf64325be8000b0662a2f9695c0fa53465njn# error Unexpected word size 25767b1edbdf64325be8000b0662a2f9695c0fa53465njn#endif 2577e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 ); 2578e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 25798c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj 25808c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardjPRE(sys_sync) 25818c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj{ 25828c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj *flags |= SfMayBlock; 25838c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj PRINT("sys_sync ( )"); 25848c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj PRE_REG_READ0(long, "sync"); 25858c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj} 25868c9ea4ed4abe0fbee8f917a633d02368d6f59ce7sewardj 2587696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_fstatfs) 2588696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2589cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 2590a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fstatfs ( %ld, %#lx )",ARG1,ARG2); 2591696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "fstatfs", 2592696c55180aae375b48f7acc3f2aa87e13040c807sewardj unsigned int, fd, struct statfs *, buf); 2593696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) ); 2594696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2595696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2596696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_fstatfs) 2597696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2598696c55180aae375b48f7acc3f2aa87e13040c807sewardj POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) ); 2599696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2600696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2601e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_fstatfs64) 2602e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 2603cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 2604a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fstatfs64 ( %ld, %llu, %#lx )",ARG1,(ULong)ARG2,ARG3); 2605e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "fstatfs64", 2606e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj unsigned int, fd, vki_size_t, size, struct statfs64 *, buf); 2607e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 ); 2608e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 2609e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPOST(sys_fstatfs64) 2610e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 2611e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj POST_MEM_WRITE( ARG3, ARG2 ); 2612e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 2613696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2614696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_getsid) 2615696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2616a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getsid ( %ld )", ARG1); 2617696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "getsid", vki_pid_t, pid); 2618696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2619696c55180aae375b48f7acc3f2aa87e13040c807sewardj 26207b1edbdf64325be8000b0662a2f9695c0fa53465njnPRE(sys_pread64) 2621e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj{ 2622e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj *flags |= SfMayBlock; 26237b1edbdf64325be8000b0662a2f9695c0fa53465njn#if VG_WORDSIZE == 4 2624a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_pread64 ( %ld, %#lx, %llu, %lld )", 2625ca78724a71ba13f05b92455a8156206e6df27e56tom ARG1, ARG2, (ULong)ARG3, MERGE64(ARG4,ARG5)); 2626e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj PRE_REG_READ5(ssize_t, "pread64", 2627e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj unsigned int, fd, char *, buf, vki_size_t, count, 2628ca78724a71ba13f05b92455a8156206e6df27e56tom vki_u32, MERGE64_FIRST(offset), vki_u32, MERGE64_SECOND(offset)); 26297b1edbdf64325be8000b0662a2f9695c0fa53465njn#elif VG_WORDSIZE == 8 26307b1edbdf64325be8000b0662a2f9695c0fa53465njn PRINT("sys_pread64 ( %ld, %#lx, %llu, %lld )", 26317b1edbdf64325be8000b0662a2f9695c0fa53465njn ARG1, ARG2, (ULong)ARG3, (Long)ARG4); 26327b1edbdf64325be8000b0662a2f9695c0fa53465njn PRE_REG_READ4(ssize_t, "pread64", 26337b1edbdf64325be8000b0662a2f9695c0fa53465njn unsigned int, fd, char *, buf, vki_size_t, count, 26347b1edbdf64325be8000b0662a2f9695c0fa53465njn Word, offset); 26357b1edbdf64325be8000b0662a2f9695c0fa53465njn#else 26367b1edbdf64325be8000b0662a2f9695c0fa53465njn# error Unexpected word size 26377b1edbdf64325be8000b0662a2f9695c0fa53465njn#endif 2638e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 ); 2639e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj} 26407b1edbdf64325be8000b0662a2f9695c0fa53465njnPOST(sys_pread64) 2641e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj{ 2642e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj vg_assert(SUCCESS); 2643e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj if (RES > 0) { 2644e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj POST_MEM_WRITE( ARG2, RES ); 2645e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj } 2646e7aa4ae857ab875e6b673ad5a081ff6b1b697aecsewardj} 2647a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 2648a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_mknod) 2649855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 2650cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 2651a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mknod ( %#lx(%s), 0x%lx, 0x%lx )", ARG1, (char*)ARG1, ARG2, ARG3 ); 2652a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_REG_READ3(long, "mknod", 2653a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj const char *, pathname, int, mode, unsigned, dev); 2654a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 ); 2655855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 2656de4a1d01951937632098a6cda45859afa587a06fsewardj 2657696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_flock) 2658696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 2659696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 2660a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_flock ( %ld, %ld )", ARG1, ARG2 ); 2661696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation); 2662696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 2663696c55180aae375b48f7acc3f2aa87e13040c807sewardj 2664a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj// Pre_read a char** argument. 2665e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianstatic void pre_argv_envp(Addr a, ThreadId tid, const HChar* s1, const HChar* s2) 26662e1c37dfb4583a40fa1e93bc4c7285c24d152b7fnethercote{ 2667a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj while (True) { 2668a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj Addr a_deref; 2669a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj Addr* a_p = (Addr*)a; 2670a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) ); 2671a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj a_deref = *a_p; 2672a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (0 == a_deref) 2673a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj break; 2674a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_RASCIIZ( s2, a_deref ); 2675a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj a += sizeof(char*); 2676a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 26772e1c37dfb4583a40fa1e93bc4c7285c24d152b7fnethercote} 2678de4a1d01951937632098a6cda45859afa587a06fsewardj 26797b85dd57f12f86a03f51f7cedea46147ef937f82njnstatic Bool i_am_the_only_thread ( void ) 26807b85dd57f12f86a03f51f7cedea46147ef937f82njn{ 26817b85dd57f12f86a03f51f7cedea46147ef937f82njn Int c = VG_(count_living_threads)(); 26827b85dd57f12f86a03f51f7cedea46147ef937f82njn vg_assert(c >= 1); /* stay sane */ 26837b85dd57f12f86a03f51f7cedea46147ef937f82njn return c == 1; 26847b85dd57f12f86a03f51f7cedea46147ef937f82njn} 26857b85dd57f12f86a03f51f7cedea46147ef937f82njn 26867b85dd57f12f86a03f51f7cedea46147ef937f82njn/* Wait until all other threads disappear. */ 26877b85dd57f12f86a03f51f7cedea46147ef937f82njnvoid VG_(reap_threads)(ThreadId self) 26887b85dd57f12f86a03f51f7cedea46147ef937f82njn{ 26897b85dd57f12f86a03f51f7cedea46147ef937f82njn while (!i_am_the_only_thread()) { 26907b85dd57f12f86a03f51f7cedea46147ef937f82njn /* Let other thread(s) run */ 26917b85dd57f12f86a03f51f7cedea46147ef937f82njn VG_(vg_yield)(); 26927b85dd57f12f86a03f51f7cedea46147ef937f82njn VG_(poll_signals)(self); 26937b85dd57f12f86a03f51f7cedea46147ef937f82njn } 26947b85dd57f12f86a03f51f7cedea46147ef937f82njn vg_assert(i_am_the_only_thread()); 26957b85dd57f12f86a03f51f7cedea46147ef937f82njn} 26967b85dd57f12f86a03f51f7cedea46147ef937f82njn 2697a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj// XXX: prototype here seemingly doesn't match the prototype for i386-linux, 2698a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj// but it seems to work nonetheless... 2699a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_execve) 2700855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 270119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* path = NULL; /* path to executable */ 270219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar** envp = NULL; 270319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar** argv = NULL; 270419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar** arg2copy; 270519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* launcher_basename = NULL; 2706a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ThreadState* tst; 270745f4e7c91119c7d01a59f5e827c67841632c9314sewardj Int i, j, tot_args; 27087375061f0ecd9534a27ade9bb4fbe47ddce41298njn SysRes res; 2709064212709dc8988a48d2cbde5b90528952d8cd74sewardj Bool setuid_allowed, trace_this_child; 2710de4a1d01951937632098a6cda45859afa587a06fsewardj 2711a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )", ARG1, (char*)ARG1, ARG2, ARG3); 2712a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_REG_READ3(vki_off_t, "execve", 2713a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj char *, filename, char **, argv, char **, envp); 2714a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_RASCIIZ( "execve(filename)", ARG1 ); 2715a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (ARG2 != 0) 2716a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" ); 2717a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (ARG3 != 0) 2718a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" ); 2719de4a1d01951937632098a6cda45859afa587a06fsewardj 2720a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(VG_(is_valid_tid)(tid)); 2721a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj tst = VG_(get_ThreadState)(tid); 2722de4a1d01951937632098a6cda45859afa587a06fsewardj 2723a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj /* Erk. If the exec fails, then the following will have made a 2724a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj mess of things which makes it hard for us to continue. The 2725a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj right thing to do is piece everything together again in 272645f4e7c91119c7d01a59f5e827c67841632c9314sewardj POST(execve), but that's close to impossible. Instead, we make 272745f4e7c91119c7d01a59f5e827c67841632c9314sewardj an effort to check that the execve will work before actually 272845f4e7c91119c7d01a59f5e827c67841632c9314sewardj doing it. */ 2729de4a1d01951937632098a6cda45859afa587a06fsewardj 27307375061f0ecd9534a27ade9bb4fbe47ddce41298njn /* Check that the name at least begins in client-accessible storage. */ 2731064212709dc8988a48d2cbde5b90528952d8cd74sewardj if (ARG1 == 0 /* obviously bogus */ 2732064212709dc8988a48d2cbde5b90528952d8cd74sewardj || !VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) { 273345f4e7c91119c7d01a59f5e827c67841632c9314sewardj SET_STATUS_Failure( VKI_EFAULT ); 273445f4e7c91119c7d01a59f5e827c67841632c9314sewardj return; 273545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 273645f4e7c91119c7d01a59f5e827c67841632c9314sewardj 27379ab64a4d3043c251561419d0e0f51492172b1072sewardj // debug-only printing 27389ab64a4d3043c251561419d0e0f51492172b1072sewardj if (0) { 27399ab64a4d3043c251561419d0e0f51492172b1072sewardj VG_(printf)("ARG1 = %p(%s)\n", (void*)ARG1, (HChar*)ARG1); 27409ab64a4d3043c251561419d0e0f51492172b1072sewardj if (ARG2) { 27419ab64a4d3043c251561419d0e0f51492172b1072sewardj VG_(printf)("ARG2 = "); 27429ab64a4d3043c251561419d0e0f51492172b1072sewardj Int q; 27439ab64a4d3043c251561419d0e0f51492172b1072sewardj HChar** vec = (HChar**)ARG2; 27449ab64a4d3043c251561419d0e0f51492172b1072sewardj for (q = 0; vec[q]; q++) 27459ab64a4d3043c251561419d0e0f51492172b1072sewardj VG_(printf)("%p(%s) ", vec[q], vec[q]); 27469ab64a4d3043c251561419d0e0f51492172b1072sewardj VG_(printf)("\n"); 27479ab64a4d3043c251561419d0e0f51492172b1072sewardj } else { 27489ab64a4d3043c251561419d0e0f51492172b1072sewardj VG_(printf)("ARG2 = null\n"); 27499ab64a4d3043c251561419d0e0f51492172b1072sewardj } 27509ab64a4d3043c251561419d0e0f51492172b1072sewardj } 27519ab64a4d3043c251561419d0e0f51492172b1072sewardj 2752064212709dc8988a48d2cbde5b90528952d8cd74sewardj // Decide whether or not we want to follow along 27539ab64a4d3043c251561419d0e0f51492172b1072sewardj { // Make 'child_argv' be a pointer to the child's arg vector 27549ab64a4d3043c251561419d0e0f51492172b1072sewardj // (skipping the exe name) 2755518850bf0da07ed3e2244e307268ae0fd80e93a8florian const HChar** child_argv = (const HChar**)ARG2; 27569ab64a4d3043c251561419d0e0f51492172b1072sewardj if (child_argv && child_argv[0] == NULL) 27579ab64a4d3043c251561419d0e0f51492172b1072sewardj child_argv = NULL; 27589ab64a4d3043c251561419d0e0f51492172b1072sewardj trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG1, child_argv ); 27599ab64a4d3043c251561419d0e0f51492172b1072sewardj } 2760064212709dc8988a48d2cbde5b90528952d8cd74sewardj 27617375061f0ecd9534a27ade9bb4fbe47ddce41298njn // Do the important checks: it is a file, is executable, permissions are 2762c74b3ba6f1d1b269aa2abcad3bd1c58d0d630c9fsewardj // ok, etc. We allow setuid executables to run only in the case when 2763c74b3ba6f1d1b269aa2abcad3bd1c58d0d630c9fsewardj // we are not simulating them, that is, they to be run natively. 2764064212709dc8988a48d2cbde5b90528952d8cd74sewardj setuid_allowed = trace_this_child ? False : True; 2765e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian res = VG_(pre_exec_check)((const HChar *)ARG1, NULL, setuid_allowed); 2766cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sr_isError(res)) { 2767cda2f0fbda4c4b2644babc830244be8aed95de1dnjn SET_STATUS_Failure( sr_Err(res) ); 27687375061f0ecd9534a27ade9bb4fbe47ddce41298njn return; 27697375061f0ecd9534a27ade9bb4fbe47ddce41298njn } 27707375061f0ecd9534a27ade9bb4fbe47ddce41298njn 277198e68a4db8df087243c5f095cddb7b34adb2d19bsewardj /* If we're tracing the child, and the launcher name looks bogus 277298e68a4db8df087243c5f095cddb7b34adb2d19bsewardj (possibly because launcher.c couldn't figure it out, see 277398e68a4db8df087243c5f095cddb7b34adb2d19bsewardj comments therein) then we have no option but to fail. */ 2774064212709dc8988a48d2cbde5b90528952d8cd74sewardj if (trace_this_child 277598e68a4db8df087243c5f095cddb7b34adb2d19bsewardj && (VG_(name_of_launcher) == NULL 277698e68a4db8df087243c5f095cddb7b34adb2d19bsewardj || VG_(name_of_launcher)[0] != '/')) { 277798e68a4db8df087243c5f095cddb7b34adb2d19bsewardj SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */ 277898e68a4db8df087243c5f095cddb7b34adb2d19bsewardj return; 277998e68a4db8df087243c5f095cddb7b34adb2d19bsewardj } 278098e68a4db8df087243c5f095cddb7b34adb2d19bsewardj 278145f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* After this point, we can't recover if the execve fails. */ 278219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian VG_(debugLog)(1, "syswrap", "Exec of %s\n", (HChar*)ARG1); 278345f4e7c91119c7d01a59f5e827c67841632c9314sewardj 2784997546cadb1c8240e90c6e7d316ec7850626d751sewardj 2785997546cadb1c8240e90c6e7d316ec7850626d751sewardj // Terminate gdbserver if it is active. 2786997546cadb1c8240e90c6e7d316ec7850626d751sewardj if (VG_(clo_vgdb) != Vg_VgdbNo) { 2787997546cadb1c8240e90c6e7d316ec7850626d751sewardj // If the child will not be traced, we need to terminate gdbserver 2788997546cadb1c8240e90c6e7d316ec7850626d751sewardj // to cleanup the gdbserver resources (e.g. the FIFO files). 2789997546cadb1c8240e90c6e7d316ec7850626d751sewardj // If child will be traced, we also terminate gdbserver: the new 2790997546cadb1c8240e90c6e7d316ec7850626d751sewardj // Valgrind will start a fresh gdbserver after exec. 2791997546cadb1c8240e90c6e7d316ec7850626d751sewardj VG_(gdbserver) (0); 2792997546cadb1c8240e90c6e7d316ec7850626d751sewardj } 2793997546cadb1c8240e90c6e7d316ec7850626d751sewardj 2794a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj /* Resistance is futile. Nuke all other threads. POSIX mandates 2795a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj this. (Really, nuke them all, since the new process will make 2796a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj its own new thread.) */ 2797ef1cf8b3583107c7d918c60895937f09969d5b3esewardj VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread ); 27987b85dd57f12f86a03f51f7cedea46147ef937f82njn VG_(reap_threads)(tid); 2799de4a1d01951937632098a6cda45859afa587a06fsewardj 280045f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Set up the child's exe path. 280145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 2802064212709dc8988a48d2cbde5b90528952d8cd74sewardj if (trace_this_child) { 280345f4e7c91119c7d01a59f5e827c67841632c9314sewardj 280445f4e7c91119c7d01a59f5e827c67841632c9314sewardj // We want to exec the launcher. Get its pre-remembered path. 280545f4e7c91119c7d01a59f5e827c67841632c9314sewardj path = VG_(name_of_launcher); 280645f4e7c91119c7d01a59f5e827c67841632c9314sewardj // VG_(name_of_launcher) should have been acquired by m_main at 280745f4e7c91119c7d01a59f5e827c67841632c9314sewardj // startup. 280845f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(path); 280945f4e7c91119c7d01a59f5e827c67841632c9314sewardj 281045f4e7c91119c7d01a59f5e827c67841632c9314sewardj launcher_basename = VG_(strrchr)(path, '/'); 281145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (launcher_basename == NULL || launcher_basename[1] == 0) { 281245f4e7c91119c7d01a59f5e827c67841632c9314sewardj launcher_basename = path; // hmm, tres dubious 281345f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 281445f4e7c91119c7d01a59f5e827c67841632c9314sewardj launcher_basename++; 281545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 281645f4e7c91119c7d01a59f5e827c67841632c9314sewardj 281745f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 281819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian path = (HChar*)ARG1; 281945f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 282045f4e7c91119c7d01a59f5e827c67841632c9314sewardj 282145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Set up the child's environment. 282245f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 28234e1369582e21b6b614cf31ca811d8f19e88833datom // Remove the valgrind-specific stuff from the environment so the 28247b4e5ba742056c84e76434e9d220e1dc538ed1ecnjn // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc. 28254e1369582e21b6b614cf31ca811d8f19e88833datom // This is done unconditionally, since if we are tracing the child, 282645f4e7c91119c7d01a59f5e827c67841632c9314sewardj // the child valgrind will set up the appropriate client environment. 282711106992f0479d087d9f1069c9d9374b1095a0b4njn // Nb: we make a copy of the environment before trying to mangle it 282811106992f0479d087d9f1069c9d9374b1095a0b4njn // as it might be in read-only memory (this was bug #101881). 282945f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 283045f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Then, if tracing the child, set VALGRIND_LIB for it. 283145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 283245f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (ARG3 == 0) { 283345f4e7c91119c7d01a59f5e827c67841632c9314sewardj envp = NULL; 283445f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 283519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian envp = VG_(env_clone)( (HChar**)ARG3 ); 283645f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (envp == NULL) goto hosed; 28374e1369582e21b6b614cf31ca811d8f19e88833datom VG_(env_remove_valgrind_env_stuff)( envp ); 2838a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 2839de4a1d01951937632098a6cda45859afa587a06fsewardj 2840064212709dc8988a48d2cbde5b90528952d8cd74sewardj if (trace_this_child) { 284145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Set VALGRIND_LIB in ARG3 (the environment) 284245f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir)); 2843855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 2844de4a1d01951937632098a6cda45859afa587a06fsewardj 284545f4e7c91119c7d01a59f5e827c67841632c9314sewardj // Set up the child's args. If not tracing it, they are 284645f4e7c91119c7d01a59f5e827c67841632c9314sewardj // simply ARG2. Otherwise, they are 284745f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 284845f4e7c91119c7d01a59f5e827c67841632c9314sewardj // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG2[1..] 284945f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 285045f4e7c91119c7d01a59f5e827c67841632c9314sewardj // except that the first VG_(args_for_valgrind_noexecpass) args 285145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // are omitted. 285245f4e7c91119c7d01a59f5e827c67841632c9314sewardj // 2853064212709dc8988a48d2cbde5b90528952d8cd74sewardj if (!trace_this_child) { 285419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian argv = (HChar**)ARG2; 285545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } else { 285614c7cc5a5fbe9526329f058116f921988efe679esewardj vg_assert( VG_(args_for_valgrind) ); 285745f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 ); 285845f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert( VG_(args_for_valgrind_noexecpass) 285914c7cc5a5fbe9526329f058116f921988efe679esewardj <= VG_(sizeXA)( VG_(args_for_valgrind) ) ); 286045f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* how many args in total will there be? */ 286145f4e7c91119c7d01a59f5e827c67841632c9314sewardj // launcher basename 286245f4e7c91119c7d01a59f5e827c67841632c9314sewardj tot_args = 1; 286345f4e7c91119c7d01a59f5e827c67841632c9314sewardj // V's args 286414c7cc5a5fbe9526329f058116f921988efe679esewardj tot_args += VG_(sizeXA)( VG_(args_for_valgrind) ); 286545f4e7c91119c7d01a59f5e827c67841632c9314sewardj tot_args -= VG_(args_for_valgrind_noexecpass); 286645f4e7c91119c7d01a59f5e827c67841632c9314sewardj // name of client exe 286745f4e7c91119c7d01a59f5e827c67841632c9314sewardj tot_args++; 286845f4e7c91119c7d01a59f5e827c67841632c9314sewardj // args for client exe, skipping [0] 286919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian arg2copy = (HChar**)ARG2; 287045f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (arg2copy && arg2copy[0]) { 287145f4e7c91119c7d01a59f5e827c67841632c9314sewardj for (i = 1; arg2copy[i]; i++) 287245f4e7c91119c7d01a59f5e827c67841632c9314sewardj tot_args++; 287345f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 287445f4e7c91119c7d01a59f5e827c67841632c9314sewardj // allocate 28759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj argv = VG_(malloc)( "di.syswrap.pre_sys_execve.1", 28769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj (tot_args+1) * sizeof(HChar*) ); 287745f4e7c91119c7d01a59f5e827c67841632c9314sewardj // copy 287845f4e7c91119c7d01a59f5e827c67841632c9314sewardj j = 0; 287945f4e7c91119c7d01a59f5e827c67841632c9314sewardj argv[j++] = launcher_basename; 288014c7cc5a5fbe9526329f058116f921988efe679esewardj for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) { 288145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (i < VG_(args_for_valgrind_noexecpass)) 288245f4e7c91119c7d01a59f5e827c67841632c9314sewardj continue; 288314c7cc5a5fbe9526329f058116f921988efe679esewardj argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ); 288445f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 288519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian argv[j++] = (HChar*)ARG1; 288645f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (arg2copy && arg2copy[0]) 288745f4e7c91119c7d01a59f5e827c67841632c9314sewardj for (i = 1; arg2copy[i]; i++) 288845f4e7c91119c7d01a59f5e827c67841632c9314sewardj argv[j++] = arg2copy[i]; 288945f4e7c91119c7d01a59f5e827c67841632c9314sewardj argv[j++] = NULL; 289045f4e7c91119c7d01a59f5e827c67841632c9314sewardj // check 289145f4e7c91119c7d01a59f5e827c67841632c9314sewardj vg_assert(j == tot_args+1); 2892855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 2893de4a1d01951937632098a6cda45859afa587a06fsewardj 2894a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj /* restore the DATA rlimit for the child */ 2895a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data)); 28965b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote 2897a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj /* 2898a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj Set the signal state up for exec. 28995b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote 2900a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj We need to set the real signal state to make sure the exec'd 2901a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj process gets SIG_IGN properly. 2902de4a1d01951937632098a6cda45859afa587a06fsewardj 2903a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj Also set our real sigmask to match the client's sigmask so that 2904a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj the exec'd child will get the right mask. First we need to 2905a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj clear out any pending signals so they they don't get delivered, 2906a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj which would confuse things. 2907f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge 2908f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge XXX This is a bug - the signals should remain pending, and be 2909f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge delivered to the new process after exec. There's also a 2910f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge race-condition, since if someone delivers us a signal between 2911f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge the sigprocmask and the execve, we'll still get the signal. Oh 2912f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge well. 2913f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge */ 2914f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge { 291573b526fb4af0f60634f0078583d92b931d5c0eebnethercote vki_sigset_t allsigs; 291673b526fb4af0f60634f0078583d92b931d5c0eebnethercote vki_siginfo_t info; 2917b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 2918cda2f0fbda4c4b2644babc830244be8aed95de1dnjn /* What this loop does: it queries SCSS (the signal state that 2919cda2f0fbda4c4b2644babc830244be8aed95de1dnjn the client _thinks_ the kernel is in) by calling 2920cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(do_sys_sigaction), and modifies the real kernel signal 2921cda2f0fbda4c4b2644babc830244be8aed95de1dnjn state accordingly. */ 292245f4e7c91119c7d01a59f5e827c67841632c9314sewardj for (i = 1; i < VG_(max_signal); i++) { 2923cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigaction_fromK_t sa_f; 2924cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vki_sigaction_toK_t sa_t; 2925cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(do_sys_sigaction)(i, NULL, &sa_f); 2926cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(convert_sigaction_fromK_to_toK)(&sa_f, &sa_t); 2927cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (sa_t.ksa_handler == VKI_SIG_IGN) 2928cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(sigaction)(i, &sa_t, NULL); 2929b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj else { 2930cda2f0fbda4c4b2644babc830244be8aed95de1dnjn sa_t.ksa_handler = VKI_SIG_DFL; 2931cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(sigaction)(i, &sa_t, NULL); 2932b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj } 2933b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj } 2934b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 293573b526fb4af0f60634f0078583d92b931d5c0eebnethercote VG_(sigfillset)(&allsigs); 2936ef1cf8b3583107c7d918c60895937f09969d5b3esewardj while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0) 2937b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj ; 2938f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge 293973b526fb4af0f60634f0078583d92b931d5c0eebnethercote VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL); 2940f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge } 2941f0dd7e17450a6f89629bf519c8d78f5e4cc5c823fitzhardinge 294245f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (0) { 294319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar **cpp; 294445f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(printf)("exec: %s\n", path); 294545f4e7c91119c7d01a59f5e827c67841632c9314sewardj for (cpp = argv; cpp && *cpp; cpp++) 294645f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(printf)("argv: %s\n", *cpp); 294745f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (0) 294845f4e7c91119c7d01a59f5e827c67841632c9314sewardj for (cpp = envp; cpp && *cpp; cpp++) 294945f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(printf)("env: %s\n", *cpp); 295045f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 295145f4e7c91119c7d01a59f5e827c67841632c9314sewardj 2952a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_from_SysRes( 295345f4e7c91119c7d01a59f5e827c67841632c9314sewardj VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp) 2954a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ); 2955e1c06d80fa446cbe2a80de412315be1b630051a4fitzhardinge 295645f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* If we got here, then the execve failed. We've already made way 295745f4e7c91119c7d01a59f5e827c67841632c9314sewardj too much of a mess to continue, so we have to abort. */ 295845f4e7c91119c7d01a59f5e827c67841632c9314sewardj hosed: 2959dc294c3956c6d1c35862ba05833be33217b5844ftom vg_assert(FAILURE); 2960738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld\n", 2961a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart ARG1, (char*)ARG1, ARG2, ARG3, ERR); 2962b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from " 2963738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "execve() failing, so I'm dying.\n"); 2964a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), " 2965738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "or work out how to recover.\n"); 2966b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj VG_(exit)(101); 2967855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 2968855d93d2e9940890b28874520fa4c1677bf825e2jsgf 2969a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_access) 2970855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 2971a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_access ( %#lx(%s), %ld )", ARG1,(char*)ARG1,ARG2); 29729a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote PRE_REG_READ2(long, "access", const char *, pathname, int, mode); 297322cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "access(pathname)", ARG1 ); 2974855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 2975855d93d2e9940890b28874520fa4c1677bf825e2jsgf 2976a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_alarm) 2977855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 2978a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_alarm ( %ld )", ARG1); 29799a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds); 2980855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 2981855d93d2e9940890b28874520fa4c1677bf825e2jsgf 2982a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_brk) 2983855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 298498abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge Addr brk_limit = VG_(brk_limit); 2985a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj Addr brk_new; 298698abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 2987855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* libc says: int brk(void *end_data_segment); 2988855d93d2e9940890b28874520fa4c1677bf825e2jsgf kernel says: void* brk(void* end_data_segment); (more or less) 2989855d93d2e9940890b28874520fa4c1677bf825e2jsgf 2990855d93d2e9940890b28874520fa4c1677bf825e2jsgf libc returns 0 on success, and -1 (and sets errno) on failure. 2991855d93d2e9940890b28874520fa4c1677bf825e2jsgf Nb: if you ask to shrink the dataseg end below what it 2992855d93d2e9940890b28874520fa4c1677bf825e2jsgf currently is, that always succeeds, even if the dataseg end 2993855d93d2e9940890b28874520fa4c1677bf825e2jsgf doesn't actually change (eg. brk(0)). Unless it seg faults. 2994855d93d2e9940890b28874520fa4c1677bf825e2jsgf 2995855d93d2e9940890b28874520fa4c1677bf825e2jsgf Kernel returns the new dataseg end. If the brk() failed, this 2996855d93d2e9940890b28874520fa4c1677bf825e2jsgf will be unchanged from the old one. That's why calling (kernel) 2997855d93d2e9940890b28874520fa4c1677bf825e2jsgf brk(0) gives the current dataseg end (libc brk() just returns 2998855d93d2e9940890b28874520fa4c1677bf825e2jsgf zero in that case). 2999855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3000855d93d2e9940890b28874520fa4c1677bf825e2jsgf Both will seg fault if you shrink it back into a text segment. 3001855d93d2e9940890b28874520fa4c1677bf825e2jsgf */ 3002a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_brk ( %#lx )", ARG1); 30039c311eb3d0c532a972449e5e600d10f0470120b6nethercote PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment); 3004855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3005981abb5e4a0f43049ed7efac90cfa52ac61b5140florian brk_new = do_brk(ARG1, tid); 3006a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Success( brk_new ); 300798abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 3008a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (brk_new == ARG1) { 3009855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* brk() succeeded */ 3010a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (brk_new < brk_limit) { 3011855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* successfully shrunk the data segment. */ 301222cfccb218c6975fa852a1135ddce342474b99d2njn VG_TRACK( die_mem_brk, (Addr)ARG1, 301322cfccb218c6975fa852a1135ddce342474b99d2njn brk_limit-ARG1 ); 3014855d93d2e9940890b28874520fa4c1677bf825e2jsgf } else 3015a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (brk_new > brk_limit) { 3016855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* successfully grew the data segment */ 301798abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge VG_TRACK( new_mem_brk, brk_limit, 30187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj ARG1-brk_limit, tid ); 3019855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3020855d93d2e9940890b28874520fa4c1677bf825e2jsgf } else { 3021855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* brk() failed */ 3022a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(brk_limit == brk_new); 3023855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3024855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3025855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3026a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_chdir) 3027855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3028cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3029a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_chdir ( %#lx(%s) )", ARG1,(char*)ARG1); 3030c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ1(long, "chdir", const char *, path); 303122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "chdir(path)", ARG1 ); 3032855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3033855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3034a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_chmod) 3035855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3036cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3037a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_chmod ( %#lx(%s), %ld )", ARG1,(char*)ARG1,ARG2); 3038c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode); 303922cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "chmod(path)", ARG1 ); 3040855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3041855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3042e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_chown) 3043e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3044cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3045a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_chown ( %#lx(%s), 0x%lx, 0x%lx )", ARG1,(char*)ARG1,ARG2,ARG3); 3046e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "chown", 3047e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj const char *, path, vki_uid_t, owner, vki_gid_t, group); 3048e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_RASCIIZ( "chown(path)", ARG1 ); 3049e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 3050e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj 3051e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_lchown) 3052e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3053cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3054a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_lchown ( %#lx(%s), 0x%lx, 0x%lx )", ARG1,(char*)ARG1,ARG2,ARG3); 3055e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "lchown", 3056e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj const char *, path, vki_uid_t, owner, vki_gid_t, group); 3057e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_RASCIIZ( "lchown(path)", ARG1 ); 3058e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 3059a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 3060a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_close) 3061855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3062cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3063a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_close ( %ld )", ARG1); 3064c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ1(long, "close", unsigned int, fd); 3065c6851dde1b46166417a2bdb096c05818f5f07f09nethercote 3066f854867c39a3697ca53e417447048d0cc3ff8a87nethercote /* Detect and negate attempts by the client to close Valgrind's log fd */ 30679da79d1520e4ac844ef33e46a7e9aa7f2d4ee2casewardj if ( (!ML_(fd_allowed)(ARG1, "close", tid, False)) 30689da79d1520e4ac844ef33e46a7e9aa7f2d4ee2casewardj /* If doing -d style logging (which is to fd=2), don't 30699da79d1520e4ac844ef33e46a7e9aa7f2d4ee2casewardj allow that to be closed either. */ 30709da79d1520e4ac844ef33e46a7e9aa7f2d4ee2casewardj || (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0) ) 3071a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EBADF ); 3072855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3073855d93d2e9940890b28874520fa4c1677bf825e2jsgf 307485a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_close) 3075f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh{ 30761dcee097db02f9ef3ba355162c4373d90d0e895cnjn if (VG_(clo_track_fds)) record_fd_close(ARG1); 3077f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh} 3078855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3079a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_dup) 3080855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3081a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_dup ( %ld )", ARG1); 30829a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote PRE_REG_READ1(long, "dup", unsigned int, oldfd); 3083855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3084855d93d2e9940890b28874520fa4c1677bf825e2jsgf 308585a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_dup) 3086855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3087a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 30887eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(RES, "dup", tid, True)) { 308922cfccb218c6975fa852a1135ddce342474b99d2njn VG_(close)(RES); 3090a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EMFILE ); 3091f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 30929a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote if (VG_(clo_track_fds)) 3093096ccdd670d4e4eabdafb18598b1cd06d790fda8njn ML_(record_fd_open_named)(tid, RES); 3094855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3095855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3096855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3097a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_dup2) 3098855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3099a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_dup2 ( %ld, %ld )", ARG1,ARG2); 310071f05f360cf9b60b129b11d0c56e38bbd4997671nethercote PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd); 31017eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(ARG2, "dup2", tid, True)) 3102a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EBADF ); 3103855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3104855d93d2e9940890b28874520fa4c1677bf825e2jsgf 310585a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_dup2) 3106855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3107a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 310871f05f360cf9b60b129b11d0c56e38bbd4997671nethercote if (VG_(clo_track_fds)) 3109096ccdd670d4e4eabdafb18598b1cd06d790fda8njn ML_(record_fd_open_named)(tid, RES); 3110855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3111855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3112696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_fchdir) 3113696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3114cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3115a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fchdir ( %ld )", ARG1); 3116696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "fchdir", unsigned int, fd); 3117696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3118696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3119e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_fchown) 3120e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3121cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3122a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fchown ( %ld, %ld, %ld )", ARG1,ARG2,ARG3); 3123e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "fchown", 3124e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj unsigned int, fd, vki_uid_t, owner, vki_gid_t, group); 3125e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 3126696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3127696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_fchmod) 3128696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3129cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3130a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_fchmod ( %ld, %ld )", ARG1,ARG2); 3131696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode); 3132696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3133696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3134696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_newfstat) 3135696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3136cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3137a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_newfstat ( %ld, %#lx )", ARG1,ARG2); 3138696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf); 3139696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) ); 3140696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3141696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3142696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_newfstat) 3143696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3144696c55180aae375b48f7acc3f2aa87e13040c807sewardj POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); 3145696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3146855d93d2e9940890b28874520fa4c1677bf825e2jsgf 314773b526fb4af0f60634f0078583d92b931d5c0eebnethercotestatic vki_sigset_t fork_saved_mask; 3148855d93d2e9940890b28874520fa4c1677bf825e2jsgf 314975a8c98921a3f59ac0351c270b84fa1c7cc29e01nethercote// In Linux, the sys_fork() function varies across architectures, but we 315075a8c98921a3f59ac0351c270b84fa1c7cc29e01nethercote// ignore the various args it gets, and so it looks arch-neutral. Hmm. 3151a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_fork) 3152855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 315358bbd94336262ff3a01fddf9dac4a041eec9d168njn Bool is_child; 315458bbd94336262ff3a01fddf9dac4a041eec9d168njn Int child_pid; 315573b526fb4af0f60634f0078583d92b931d5c0eebnethercote vki_sigset_t mask; 3156855d93d2e9940890b28874520fa4c1677bf825e2jsgf 315775a8c98921a3f59ac0351c270b84fa1c7cc29e01nethercote PRINT("sys_fork ( )"); 315875a8c98921a3f59ac0351c270b84fa1c7cc29e01nethercote PRE_REG_READ0(long, "fork"); 315975a8c98921a3f59ac0351c270b84fa1c7cc29e01nethercote 3160855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* Block all signals during fork, so that we can fix things up in 3161855d93d2e9940890b28874520fa4c1677bf825e2jsgf the child without being interrupted. */ 316273b526fb4af0f60634f0078583d92b931d5c0eebnethercote VG_(sigfillset)(&mask); 316373b526fb4af0f60634f0078583d92b931d5c0eebnethercote VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask); 3164855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3165a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) ); 3166855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3167cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!SUCCESS) return; 3168cda2f0fbda4c4b2644babc830244be8aed95de1dnjn 31696e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#if defined(VGO_linux) 317058bbd94336262ff3a01fddf9dac4a041eec9d168njn // RES is 0 for child, non-0 (the child's PID) for parent. 317158bbd94336262ff3a01fddf9dac4a041eec9d168njn is_child = ( RES == 0 ? True : False ); 317258bbd94336262ff3a01fddf9dac4a041eec9d168njn child_pid = ( is_child ? -1 : RES ); 3173f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGO_darwin) 3174f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // RES is the child's pid. RESHI is 1 for child, 0 for parent. 3175f76d27a697a7b0bf3b84490baf60623fc96a23afnjn is_child = RESHI; 3176f76d27a697a7b0bf3b84490baf60623fc96a23afnjn child_pid = RES; 3177f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else 3178f76d27a697a7b0bf3b84490baf60623fc96a23afnjn# error Unknown OS 3179f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 3180cda2f0fbda4c4b2644babc830244be8aed95de1dnjn 3181e9ba34af88cd1b397957018e3e122869c76c1652njn VG_(do_atfork_pre)(tid); 3182e9ba34af88cd1b397957018e3e122869c76c1652njn 318358bbd94336262ff3a01fddf9dac4a041eec9d168njn if (is_child) { 3184b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj VG_(do_atfork_child)(tid); 3185855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3186855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* restore signal mask */ 318773b526fb4af0f60634f0078583d92b931d5c0eebnethercote VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); 31886e31f80899f1c79a54f164955069f3f74fe8b7e2sewardj 31896e31f80899f1c79a54f164955069f3f74fe8b7e2sewardj /* If --child-silent-after-fork=yes was specified, set the 3190738856f99eea33d86ce91dcb1d6cd5b151e307casewardj output file descriptors to 'impossible' values. This is 31916e31f80899f1c79a54f164955069f3f74fe8b7e2sewardj noticed by send_bytes_to_logging_sink in m_libcprint.c, which 3192738856f99eea33d86ce91dcb1d6cd5b151e307casewardj duly stops writing any further output. */ 3193738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (VG_(clo_child_silent_after_fork)) { 3194738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (!VG_(log_output_sink).is_socket) 3195738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(log_output_sink).fd = -1; 3196738856f99eea33d86ce91dcb1d6cd5b151e307casewardj if (!VG_(xml_output_sink).is_socket) 3197738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(xml_output_sink).fd = -1; 3198738856f99eea33d86ce91dcb1d6cd5b151e307casewardj } 319958bbd94336262ff3a01fddf9dac4a041eec9d168njn 3200f76d27a697a7b0bf3b84490baf60623fc96a23afnjn } else { 3201e9ba34af88cd1b397957018e3e122869c76c1652njn VG_(do_atfork_parent)(tid); 3202e9ba34af88cd1b397957018e3e122869c76c1652njn 320358bbd94336262ff3a01fddf9dac4a041eec9d168njn PRINT(" fork: process %d created child %d\n", VG_(getpid)(), child_pid); 3204855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3205855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* restore signal mask */ 320673b526fb4af0f60634f0078583d92b931d5c0eebnethercote VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL); 3207855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3208855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3209855d93d2e9940890b28874520fa4c1677bf825e2jsgf 32108c257323279d9036a3d0e283c8c5cd3ee9bb5ee0sewardjPRE(sys_ftruncate) 32118c257323279d9036a3d0e283c8c5cd3ee9bb5ee0sewardj{ 32128c257323279d9036a3d0e283c8c5cd3ee9bb5ee0sewardj *flags |= SfMayBlock; 3213a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_ftruncate ( %ld, %ld )", ARG1,ARG2); 32148c257323279d9036a3d0e283c8c5cd3ee9bb5ee0sewardj PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length); 32158c257323279d9036a3d0e283c8c5cd3ee9bb5ee0sewardj} 32168c257323279d9036a3d0e283c8c5cd3ee9bb5ee0sewardj 3217696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_truncate) 3218696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3219696c55180aae375b48f7acc3f2aa87e13040c807sewardj *flags |= SfMayBlock; 3220a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_truncate ( %#lx(%s), %ld )", ARG1,(char*)ARG1,ARG2); 3221696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "truncate", 3222696c55180aae375b48f7acc3f2aa87e13040c807sewardj const char *, path, unsigned long, length); 3223696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_RASCIIZ( "truncate(path)", ARG1 ); 3224696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3225696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3226e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_ftruncate64) 3227e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3228e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj *flags |= SfMayBlock; 322989d43f79c020c46b895e2ae916f61e2555636ec8njn#if VG_WORDSIZE == 4 3230ca78724a71ba13f05b92455a8156206e6df27e56tom PRINT("sys_ftruncate64 ( %ld, %lld )", ARG1, MERGE64(ARG2,ARG3)); 3231e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "ftruncate64", 3232e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj unsigned int, fd, 3233ca78724a71ba13f05b92455a8156206e6df27e56tom UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length)); 323489d43f79c020c46b895e2ae916f61e2555636ec8njn#else 323589d43f79c020c46b895e2ae916f61e2555636ec8njn PRINT("sys_ftruncate64 ( %ld, %lld )", ARG1, (Long)ARG2); 323689d43f79c020c46b895e2ae916f61e2555636ec8njn PRE_REG_READ2(long, "ftruncate64", 323789d43f79c020c46b895e2ae916f61e2555636ec8njn unsigned int,fd, UWord,length); 3238e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj#endif 323989d43f79c020c46b895e2ae916f61e2555636ec8njn} 3240e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj 3241e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_truncate64) 3242e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3243e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj *flags |= SfMayBlock; 324489d43f79c020c46b895e2ae916f61e2555636ec8njn#if VG_WORDSIZE == 4 3245ca78724a71ba13f05b92455a8156206e6df27e56tom PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)MERGE64(ARG2, ARG3)); 3246e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "truncate64", 3247e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj const char *, path, 3248ca78724a71ba13f05b92455a8156206e6df27e56tom UWord, MERGE64_FIRST(length), UWord, MERGE64_SECOND(length)); 324989d43f79c020c46b895e2ae916f61e2555636ec8njn#else 325089d43f79c020c46b895e2ae916f61e2555636ec8njn PRINT("sys_truncate64 ( %#lx, %lld )", ARG1, (Long)ARG2); 325189d43f79c020c46b895e2ae916f61e2555636ec8njn PRE_REG_READ2(long, "truncate64", 325289d43f79c020c46b895e2ae916f61e2555636ec8njn const char *,path, UWord,length); 325389d43f79c020c46b895e2ae916f61e2555636ec8njn#endif 3254e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 ); 3255e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 325678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 325778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_getdents) 325878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 325978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj *flags |= SfMayBlock; 3260a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getdents ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3); 326178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ3(long, "getdents", 326299e644a7331b25402760211be907c679431ceb8eflorian unsigned int, fd, struct vki_dirent *, dirp, 326378b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj unsigned int, count); 326478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 ); 326578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 326678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 326778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPOST(sys_getdents) 326878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 326978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj vg_assert(SUCCESS); 327078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj if (RES > 0) 327178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj POST_MEM_WRITE( ARG2, RES ); 327278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 3273a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 3274a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_getdents64) 3275a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj{ 327678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj *flags |= SfMayBlock; 3277a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getdents64 ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); 327806c7bd748d9b40861e8a764e4947b30a787fef2bnethercote PRE_REG_READ3(long, "getdents64", 327999e644a7331b25402760211be907c679431ceb8eflorian unsigned int, fd, struct vki_dirent64 *, dirp, 328006c7bd748d9b40861e8a764e4947b30a787fef2bnethercote unsigned int, count); 328122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "getdents64(dirp)", ARG2, ARG3 ); 3282855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3283855d93d2e9940890b28874520fa4c1677bf825e2jsgf 328485a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_getdents64) 3285855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3286a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 328722cfccb218c6975fa852a1135ddce342474b99d2njn if (RES > 0) 328822cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, RES ); 3289855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3290855d93d2e9940890b28874520fa4c1677bf825e2jsgf 329178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_getgroups) 329278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 3293a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getgroups ( %ld, %#lx )", ARG1, ARG2); 329478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list); 329578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj if (ARG1 > 0) 329678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) ); 329778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 329878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 329978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPOST(sys_getgroups) 330078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 330178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj vg_assert(SUCCESS); 330278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj if (ARG1 > 0 && RES > 0) 330378b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) ); 330478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 3305a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 3306a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_getcwd) 3307855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 33084b70e8c73ee9d28ece852b781457f0b19359e513njn // Comment from linux/fs/dcache.c: 33094b70e8c73ee9d28ece852b781457f0b19359e513njn // NOTE! The user-level library version returns a character pointer. 33104b70e8c73ee9d28ece852b781457f0b19359e513njn // The kernel system call just returns the length of the buffer filled 33114b70e8c73ee9d28ece852b781457f0b19359e513njn // (which includes the ending '\0' character), or a negative error 33124b70e8c73ee9d28ece852b781457f0b19359e513njn // value. 33134b70e8c73ee9d28ece852b781457f0b19359e513njn // Is this Linux-specific? If so it should be moved to syswrap-linux.c. 3314a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getcwd ( %#lx, %llu )", ARG1,(ULong)ARG2); 3315ac866b9f2f428e733f7e01e9e84d761785720092nethercote PRE_REG_READ2(long, "getcwd", char *, buf, unsigned long, size); 331622cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "getcwd(buf)", ARG1, ARG2 ); 3317855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3318855d93d2e9940890b28874520fa4c1677bf825e2jsgf 331985a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_getcwd) 3320855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3321a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 332222cfccb218c6975fa852a1135ddce342474b99d2njn if (RES != (Addr)NULL) 332322cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG1, RES ); 3324855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3325855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3326a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_geteuid) 3327855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 33280df495a33f39817e5cabbe94f3a5159f178d1a3anethercote PRINT("sys_geteuid ( )"); 33290df495a33f39817e5cabbe94f3a5159f178d1a3anethercote PRE_REG_READ0(long, "geteuid"); 3330855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3331855d93d2e9940890b28874520fa4c1677bf825e2jsgf 333278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_getegid) 333378b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 333478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRINT("sys_getegid ( )"); 333578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ0(long, "getegid"); 333678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 333778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 333878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_getgid) 333978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 334078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRINT("sys_getgid ( )"); 334178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ0(long, "getgid"); 334278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 3343a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 3344a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_getpid) 3345855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 33464e632c27da75082fb80efae45bbf5f7fbf8a2e3enethercote PRINT("sys_getpid ()"); 33474e632c27da75082fb80efae45bbf5f7fbf8a2e3enethercote PRE_REG_READ0(long, "getpid"); 3348855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3349855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3350696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_getpgid) 3351696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3352a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getpgid ( %ld )", ARG1); 3353696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "getpgid", vki_pid_t, pid); 3354696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 335578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 335678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_getpgrp) 335778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 335878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRINT("sys_getpgrp ()"); 335978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ0(long, "getpgrp"); 336078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 3361855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3362a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_getppid) 3363855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 33644e632c27da75082fb80efae45bbf5f7fbf8a2e3enethercote PRINT("sys_getppid ()"); 33654e632c27da75082fb80efae45bbf5f7fbf8a2e3enethercote PRE_REG_READ0(long, "getppid"); 3366855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3367855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3368cf45fd43a838e8cec32e9f3279fdc9fc893569bcnjnstatic void common_post_getrlimit(ThreadId tid, UWord a1, UWord a2) 3369855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3370620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote POST_MEM_WRITE( a2, sizeof(struct vki_rlimit) ); 3371620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote 3372f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#ifdef _RLIMIT_POSIX_FLAG 3373f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // Darwin will sometimes set _RLIMIT_POSIX_FLAG on getrlimit calls. 3374f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // Unset it here to make the switch case below work correctly. 3375f76d27a697a7b0bf3b84490baf60623fc96a23afnjn a1 &= ~_RLIMIT_POSIX_FLAG; 3376f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 3377f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 3378620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote switch (a1) { 3379620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote case VKI_RLIMIT_NOFILE: 3380620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote ((struct vki_rlimit *)a2)->rlim_cur = VG_(fd_soft_limit); 3381620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote ((struct vki_rlimit *)a2)->rlim_max = VG_(fd_hard_limit); 3382620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote break; 3383620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote 3384620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote case VKI_RLIMIT_DATA: 3385620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote *((struct vki_rlimit *)a2) = VG_(client_rlimit_data); 3386620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote break; 3387620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote 3388620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote case VKI_RLIMIT_STACK: 3389620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote *((struct vki_rlimit *)a2) = VG_(client_rlimit_stack); 3390620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote break; 339189d43f79c020c46b895e2ae916f61e2555636ec8njn } 3392855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3393855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3394696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_old_getrlimit) 3395696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3396a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_old_getrlimit ( %ld, %#lx )", ARG1,ARG2); 3397696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "old_getrlimit", 3398696c55180aae375b48f7acc3f2aa87e13040c807sewardj unsigned int, resource, struct rlimit *, rlim); 3399696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) ); 3400696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3401696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3402696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_old_getrlimit) 3403696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3404696c55180aae375b48f7acc3f2aa87e13040c807sewardj common_post_getrlimit(tid, ARG1, ARG2); 3405696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3406c37184fb0f44d188b801f7950a028a9d414b2322thughes 3407a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_getrlimit) 3408620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote{ 3409a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getrlimit ( %ld, %#lx )", ARG1,ARG2); 3410620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote PRE_REG_READ2(long, "getrlimit", 3411620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote unsigned int, resource, struct rlimit *, rlim); 341222cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) ); 3413855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3414855d93d2e9940890b28874520fa4c1677bf825e2jsgf 341585a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_getrlimit) 3416620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote{ 341722cfccb218c6975fa852a1135ddce342474b99d2njn common_post_getrlimit(tid, ARG1, ARG2); 3418620154f29bdbf44659addf9ef6ed2eed6eee934cnethercote} 3419855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3420696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_getrusage) 3421696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3422a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_getrusage ( %ld, %#lx )", ARG1,ARG2); 3423696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage); 3424696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) ); 3425696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3426696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3427696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_getrusage) 3428696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3429696c55180aae375b48f7acc3f2aa87e13040c807sewardj vg_assert(SUCCESS); 3430696c55180aae375b48f7acc3f2aa87e13040c807sewardj if (RES == 0) 3431696c55180aae375b48f7acc3f2aa87e13040c807sewardj POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) ); 3432696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3433855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3434a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_gettimeofday) 3435855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3436a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_gettimeofday ( %#lx, %#lx )", ARG1,ARG2); 3437686b5db44f043ebb74f3db0fa3b803de3f313b60nethercote PRE_REG_READ2(long, "gettimeofday", 3438686b5db44f043ebb74f3db0fa3b803de3f313b60nethercote struct timeval *, tv, struct timezone *, tz); 3439f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // GrP fixme does darwin write to *tz anymore? 344072bbd8d24c6bd39734f465ce8d54904b6865de9bnjn if (ARG1 != 0) 344172bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_WRITE( "gettimeofday(tv)", ARG1 ); 344222cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != 0) 344322cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "gettimeofday(tz)", ARG2, sizeof(struct vki_timezone) ); 3444855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3445855d93d2e9940890b28874520fa4c1677bf825e2jsgf 344685a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_gettimeofday) 3447855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3448a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 344922cfccb218c6975fa852a1135ddce342474b99d2njn if (RES == 0) { 345072bbd8d24c6bd39734f465ce8d54904b6865de9bnjn if (ARG1 != 0) 345172bbd8d24c6bd39734f465ce8d54904b6865de9bnjn POST_timeval_WRITE( ARG1 ); 345222cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != 0) 345322cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, sizeof(struct vki_timezone) ); 3454855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3455855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3456855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3457696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_settimeofday) 3458696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3459a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_settimeofday ( %#lx, %#lx )", ARG1,ARG2); 3460696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "settimeofday", 3461696c55180aae375b48f7acc3f2aa87e13040c807sewardj struct timeval *, tv, struct timezone *, tz); 346272bbd8d24c6bd39734f465ce8d54904b6865de9bnjn if (ARG1 != 0) 3463da8549df7939ee3024938cdd8a4cc64e6c2279b8njn PRE_timeval_READ( "settimeofday(tv)", ARG1 ); 3464696c55180aae375b48f7acc3f2aa87e13040c807sewardj if (ARG2 != 0) { 3465696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) ); 3466696c55180aae375b48f7acc3f2aa87e13040c807sewardj /* maybe should warn if tz->tz_dsttime is non-zero? */ 3467696c55180aae375b48f7acc3f2aa87e13040c807sewardj } 3468696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3469686b5db44f043ebb74f3db0fa3b803de3f313b60nethercote 3470a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_getuid) 3471855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 34720df495a33f39817e5cabbe94f3a5159f178d1a3anethercote PRINT("sys_getuid ( )"); 34730df495a33f39817e5cabbe94f3a5159f178d1a3anethercote PRE_REG_READ0(long, "getuid"); 3474855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3475855d93d2e9940890b28874520fa4c1677bf825e2jsgf 34761be9cf6df71305bb799823cefb48349df8229b7fnjnvoid ML_(PRE_unknown_ioctl)(ThreadId tid, UWord request, UWord arg) 34771be9cf6df71305bb799823cefb48349df8229b7fnjn{ 34781be9cf6df71305bb799823cefb48349df8229b7fnjn /* We don't have any specific information on it, so 34791be9cf6df71305bb799823cefb48349df8229b7fnjn try to do something reasonable based on direction and 34801be9cf6df71305bb799823cefb48349df8229b7fnjn size bits. The encoding scheme is described in 34811be9cf6df71305bb799823cefb48349df8229b7fnjn /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h . 34821be9cf6df71305bb799823cefb48349df8229b7fnjn 34831be9cf6df71305bb799823cefb48349df8229b7fnjn According to Simon Hausmann, _IOC_READ means the kernel 34841be9cf6df71305bb799823cefb48349df8229b7fnjn writes a value to the ioctl value passed from the user 34851be9cf6df71305bb799823cefb48349df8229b7fnjn space and the other way around with _IOC_WRITE. */ 34861be9cf6df71305bb799823cefb48349df8229b7fnjn 34871be9cf6df71305bb799823cefb48349df8229b7fnjn UInt dir = _VKI_IOC_DIR(request); 34881be9cf6df71305bb799823cefb48349df8229b7fnjn UInt size = _VKI_IOC_SIZE(request); 3489ec905f7ed1659f2251045114c785659fbb11ea88philippe if (SimHintiS(SimHint_lax_ioctls, VG_(clo_sim_hints))) { 34901be9cf6df71305bb799823cefb48349df8229b7fnjn /* 34911be9cf6df71305bb799823cefb48349df8229b7fnjn * Be very lax about ioctl handling; the only 34921be9cf6df71305bb799823cefb48349df8229b7fnjn * assumption is that the size is correct. Doesn't 34931be9cf6df71305bb799823cefb48349df8229b7fnjn * require the full buffer to be initialized when 34941be9cf6df71305bb799823cefb48349df8229b7fnjn * writing. Without this, using some device 34951be9cf6df71305bb799823cefb48349df8229b7fnjn * drivers with a large number of strange ioctl 34961be9cf6df71305bb799823cefb48349df8229b7fnjn * commands becomes very tiresome. 34971be9cf6df71305bb799823cefb48349df8229b7fnjn */ 34981be9cf6df71305bb799823cefb48349df8229b7fnjn } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) { 3499d77a4ca487d41f26235601cbcd2af73d5f61cedbbart static UWord unknown_ioctl[10]; 3500d77a4ca487d41f26235601cbcd2af73d5f61cedbbart static Int moans = sizeof(unknown_ioctl) / sizeof(unknown_ioctl[0]); 3501d77a4ca487d41f26235601cbcd2af73d5f61cedbbart 35021be9cf6df71305bb799823cefb48349df8229b7fnjn if (moans > 0 && !VG_(clo_xml)) { 3503d77a4ca487d41f26235601cbcd2af73d5f61cedbbart /* Check if have not already moaned for this request. */ 3504d77a4ca487d41f26235601cbcd2af73d5f61cedbbart UInt i; 3505d77a4ca487d41f26235601cbcd2af73d5f61cedbbart for (i = 0; i < sizeof(unknown_ioctl)/sizeof(unknown_ioctl[0]); i++) { 3506d77a4ca487d41f26235601cbcd2af73d5f61cedbbart if (unknown_ioctl[i] == request) 3507d77a4ca487d41f26235601cbcd2af73d5f61cedbbart break; 3508d77a4ca487d41f26235601cbcd2af73d5f61cedbbart if (unknown_ioctl[i] == 0) { 3509d77a4ca487d41f26235601cbcd2af73d5f61cedbbart unknown_ioctl[i] = request; 3510d77a4ca487d41f26235601cbcd2af73d5f61cedbbart moans--; 3511d77a4ca487d41f26235601cbcd2af73d5f61cedbbart VG_(umsg)("Warning: noted but unhandled ioctl 0x%lx" 3512d77a4ca487d41f26235601cbcd2af73d5f61cedbbart " with no size/direction hints.\n", request); 3513d77a4ca487d41f26235601cbcd2af73d5f61cedbbart VG_(umsg)(" This could cause spurious value errors to appear.\n"); 3514d77a4ca487d41f26235601cbcd2af73d5f61cedbbart VG_(umsg)(" See README_MISSING_SYSCALL_OR_IOCTL for " 3515d77a4ca487d41f26235601cbcd2af73d5f61cedbbart "guidance on writing a proper wrapper.\n" ); 3516d77a4ca487d41f26235601cbcd2af73d5f61cedbbart //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 3517d77a4ca487d41f26235601cbcd2af73d5f61cedbbart return; 3518d77a4ca487d41f26235601cbcd2af73d5f61cedbbart } 3519d77a4ca487d41f26235601cbcd2af73d5f61cedbbart } 35201be9cf6df71305bb799823cefb48349df8229b7fnjn } 35211be9cf6df71305bb799823cefb48349df8229b7fnjn } else { 35221be9cf6df71305bb799823cefb48349df8229b7fnjn //VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request); 35231be9cf6df71305bb799823cefb48349df8229b7fnjn //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); 35241be9cf6df71305bb799823cefb48349df8229b7fnjn if ((dir & _VKI_IOC_WRITE) && size > 0) 35251be9cf6df71305bb799823cefb48349df8229b7fnjn PRE_MEM_READ( "ioctl(generic)", arg, size); 35261be9cf6df71305bb799823cefb48349df8229b7fnjn if ((dir & _VKI_IOC_READ) && size > 0) 35271be9cf6df71305bb799823cefb48349df8229b7fnjn PRE_MEM_WRITE( "ioctl(generic)", arg, size); 35281be9cf6df71305bb799823cefb48349df8229b7fnjn } 35291be9cf6df71305bb799823cefb48349df8229b7fnjn} 35301be9cf6df71305bb799823cefb48349df8229b7fnjn 35311be9cf6df71305bb799823cefb48349df8229b7fnjnvoid ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg) 35321be9cf6df71305bb799823cefb48349df8229b7fnjn{ 35331be9cf6df71305bb799823cefb48349df8229b7fnjn /* We don't have any specific information on it, so 35341be9cf6df71305bb799823cefb48349df8229b7fnjn try to do something reasonable based on direction and 35351be9cf6df71305bb799823cefb48349df8229b7fnjn size bits. The encoding scheme is described in 35361be9cf6df71305bb799823cefb48349df8229b7fnjn /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h . 35371be9cf6df71305bb799823cefb48349df8229b7fnjn 35381be9cf6df71305bb799823cefb48349df8229b7fnjn According to Simon Hausmann, _IOC_READ means the kernel 35391be9cf6df71305bb799823cefb48349df8229b7fnjn writes a value to the ioctl value passed from the user 35401be9cf6df71305bb799823cefb48349df8229b7fnjn space and the other way around with _IOC_WRITE. */ 35411be9cf6df71305bb799823cefb48349df8229b7fnjn 35421be9cf6df71305bb799823cefb48349df8229b7fnjn UInt dir = _VKI_IOC_DIR(request); 35431be9cf6df71305bb799823cefb48349df8229b7fnjn UInt size = _VKI_IOC_SIZE(request); 35441be9cf6df71305bb799823cefb48349df8229b7fnjn if (size > 0 && (dir & _VKI_IOC_READ) 35451be9cf6df71305bb799823cefb48349df8229b7fnjn && res == 0 35461be9cf6df71305bb799823cefb48349df8229b7fnjn && arg != (Addr)NULL) 35471be9cf6df71305bb799823cefb48349df8229b7fnjn { 35481be9cf6df71305bb799823cefb48349df8229b7fnjn POST_MEM_WRITE(arg, size); 35491be9cf6df71305bb799823cefb48349df8229b7fnjn } 35501be9cf6df71305bb799823cefb48349df8229b7fnjn} 3551855d93d2e9940890b28874520fa4c1677bf825e2jsgf 355203f1e58116abbf9aef5090b34e5bcf39f455ec04njn/* 355303f1e58116abbf9aef5090b34e5bcf39f455ec04njn If we're sending a SIGKILL to one of our own threads, then simulate 355403f1e58116abbf9aef5090b34e5bcf39f455ec04njn it rather than really sending the signal, so that the target thread 355503f1e58116abbf9aef5090b34e5bcf39f455ec04njn gets a chance to clean up. Returns True if we did the killing (or 355603f1e58116abbf9aef5090b34e5bcf39f455ec04njn no killing is necessary), and False if the caller should use the 355703f1e58116abbf9aef5090b34e5bcf39f455ec04njn normal kill syscall. 355803f1e58116abbf9aef5090b34e5bcf39f455ec04njn 355903f1e58116abbf9aef5090b34e5bcf39f455ec04njn "pid" is any pid argument which can be passed to kill; group kills 356003f1e58116abbf9aef5090b34e5bcf39f455ec04njn (< -1, 0), and owner kills (-1) are ignored, on the grounds that 356103f1e58116abbf9aef5090b34e5bcf39f455ec04njn they'll most likely hit all the threads and we won't need to worry 356203f1e58116abbf9aef5090b34e5bcf39f455ec04njn about cleanup. In truth, we can't fully emulate these multicast 356303f1e58116abbf9aef5090b34e5bcf39f455ec04njn kills. 356403f1e58116abbf9aef5090b34e5bcf39f455ec04njn 356503f1e58116abbf9aef5090b34e5bcf39f455ec04njn "tgid" is a thread group id. If it is not -1, then the target 356603f1e58116abbf9aef5090b34e5bcf39f455ec04njn thread must be in that thread group. 356703f1e58116abbf9aef5090b34e5bcf39f455ec04njn */ 35687eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjBool ML_(do_sigkill)(Int pid, Int tgid) 356903f1e58116abbf9aef5090b34e5bcf39f455ec04njn{ 357003f1e58116abbf9aef5090b34e5bcf39f455ec04njn ThreadState *tst; 357103f1e58116abbf9aef5090b34e5bcf39f455ec04njn ThreadId tid; 357203f1e58116abbf9aef5090b34e5bcf39f455ec04njn 357303f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (pid <= 0) 357403f1e58116abbf9aef5090b34e5bcf39f455ec04njn return False; 357503f1e58116abbf9aef5090b34e5bcf39f455ec04njn 35764278172aee9a9db96cc2f9aff9158e3164fa113csewardj tid = VG_(lwpid_to_vgtid)(pid); 357703f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (tid == VG_INVALID_THREADID) 357803f1e58116abbf9aef5090b34e5bcf39f455ec04njn return False; /* none of our threads */ 357903f1e58116abbf9aef5090b34e5bcf39f455ec04njn 358003f1e58116abbf9aef5090b34e5bcf39f455ec04njn tst = VG_(get_ThreadState)(tid); 358103f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (tst == NULL || tst->status == VgTs_Empty) 358203f1e58116abbf9aef5090b34e5bcf39f455ec04njn return False; /* hm, shouldn't happen */ 358303f1e58116abbf9aef5090b34e5bcf39f455ec04njn 358403f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (tgid != -1 && tst->os_state.threadgroup != tgid) 358503f1e58116abbf9aef5090b34e5bcf39f455ec04njn return False; /* not the right thread group */ 358603f1e58116abbf9aef5090b34e5bcf39f455ec04njn 358703f1e58116abbf9aef5090b34e5bcf39f455ec04njn /* Check to see that the target isn't already exiting. */ 358803f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (!VG_(is_exiting)(tid)) { 358903f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (VG_(clo_trace_signals)) 3590738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_DebugMsg, 3591738856f99eea33d86ce91dcb1d6cd5b151e307casewardj "Thread %d being killed with SIGKILL\n", 3592738856f99eea33d86ce91dcb1d6cd5b151e307casewardj tst->tid); 359303f1e58116abbf9aef5090b34e5bcf39f455ec04njn 359403f1e58116abbf9aef5090b34e5bcf39f455ec04njn tst->exitreason = VgSrc_FatalSig; 359503f1e58116abbf9aef5090b34e5bcf39f455ec04njn tst->os_state.fatalsig = VKI_SIGKILL; 359603f1e58116abbf9aef5090b34e5bcf39f455ec04njn 359703f1e58116abbf9aef5090b34e5bcf39f455ec04njn if (!VG_(is_running_thread)(tid)) 3598ef1cf8b3583107c7d918c60895937f09969d5b3esewardj VG_(get_thread_out_of_syscall)(tid); 359903f1e58116abbf9aef5090b34e5bcf39f455ec04njn } 360003f1e58116abbf9aef5090b34e5bcf39f455ec04njn 360103f1e58116abbf9aef5090b34e5bcf39f455ec04njn return True; 360203f1e58116abbf9aef5090b34e5bcf39f455ec04njn} 360303f1e58116abbf9aef5090b34e5bcf39f455ec04njn 3604a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_kill) 3605855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3606a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_kill ( %ld, %ld )", ARG1,ARG2); 36079a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote PRE_REG_READ2(long, "kill", int, pid, int, sig); 36087eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(client_signal_OK)(ARG2)) { 3609a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EINVAL ); 361003f1e58116abbf9aef5090b34e5bcf39f455ec04njn return; 361103f1e58116abbf9aef5090b34e5bcf39f455ec04njn } 361203f1e58116abbf9aef5090b34e5bcf39f455ec04njn 361303f1e58116abbf9aef5090b34e5bcf39f455ec04njn /* If we're sending SIGKILL, check to see if the target is one of 361403f1e58116abbf9aef5090b34e5bcf39f455ec04njn our threads and handle it specially. */ 36157eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (ARG2 == VKI_SIGKILL && ML_(do_sigkill)(ARG1, -1)) 3616a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Success(0); 361703f1e58116abbf9aef5090b34e5bcf39f455ec04njn else 3618cda2f0fbda4c4b2644babc830244be8aed95de1dnjn /* re syscall3: Darwin has a 3rd arg, which is a flag (boolean) 3619cda2f0fbda4c4b2644babc830244be8aed95de1dnjn affecting how posix-compliant the call is. I guess it is 3620cda2f0fbda4c4b2644babc830244be8aed95de1dnjn harmless to pass the 3rd arg on other platforms; hence pass 3621cda2f0fbda4c4b2644babc830244be8aed95de1dnjn it on all. */ 3622cda2f0fbda4c4b2644babc830244be8aed95de1dnjn SET_STATUS_from_SysRes( VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3) ); 3623855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3624b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj if (VG_(clo_trace_signals)) 3625738856f99eea33d86ce91dcb1d6cd5b151e307casewardj VG_(message)(Vg_DebugMsg, "kill: sent signal %ld to pid %ld\n", 3626a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ARG2, ARG1); 3627855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3628a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj /* This kill might have given us a pending signal. Ask for a check once 3629a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj the syscall is done. */ 3630a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfPollAfter; 3631855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3632855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3633a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_link) 3634855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3635a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 3636a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_link ( %#lx(%s), %#lx(%s) )", ARG1,(char*)ARG1,ARG2,(char*)ARG2); 3637a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath); 3638a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_RASCIIZ( "link(oldpath)", ARG1); 3639a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_RASCIIZ( "link(newpath)", ARG2); 3640855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3641855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3642696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_newlstat) 3643696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3644a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_newlstat ( %#lx(%s), %#lx )", ARG1,(char*)ARG1,ARG2); 3645696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf); 3646696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 ); 3647696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) ); 3648696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3649696c55180aae375b48f7acc3f2aa87e13040c807sewardj 3650696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_newlstat) 3651696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 3652696c55180aae375b48f7acc3f2aa87e13040c807sewardj vg_assert(SUCCESS); 36539331c7b3e370971945f47e6c5f647a728ae0815anjn POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); 3654696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 3655a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 3656a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_mkdir) 3657a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj{ 3658a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 3659a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mkdir ( %#lx(%s), %ld )", ARG1,(char*)ARG1,ARG2); 36609a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode); 366122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 ); 3662855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3663855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3664a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_mprotect) 3665855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3666a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mprotect ( %#lx, %llu, %ld )", ARG1,(ULong)ARG2,ARG3); 366706c7bd748d9b40861e8a764e4947b30a787fef2bnethercote PRE_REG_READ3(long, "mprotect", 366806c7bd748d9b40861e8a764e4947b30a787fef2bnethercote unsigned long, addr, vki_size_t, len, unsigned long, prot); 366998abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 367065505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "mprotect")) { 3671a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_ENOMEM ); 3672337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj } 3673f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(VKI_PROT_GROWSDOWN) 3674337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj else 3675337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj if (ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP)) { 3676337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj /* Deal with mprotects on growable stack areas. 3677337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj 3678337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj The critical files to understand all this are mm/mprotect.c 3679337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj in the kernel and sysdeps/unix/sysv/linux/dl-execstack.c in 3680337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj glibc. 3681337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj 3682337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj The kernel provides PROT_GROWSDOWN and PROT_GROWSUP which 3683337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj round the start/end address of mprotect to the start/end of 3684337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj the underlying vma and glibc uses that as an easy way to 3685337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj change the protection of the stack by calling mprotect on the 3686337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj last page of the stack with PROT_GROWSDOWN set. 3687337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj 3688337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj The sanity check provided by the kernel is that the vma must 3689337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj have the VM_GROWSDOWN/VM_GROWSUP flag set as appropriate. */ 369065505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom UInt grows = ARG3 & (VKI_PROT_GROWSDOWN|VKI_PROT_GROWSUP); 3691ef1cf8b3583107c7d918c60895937f09969d5b3esewardj NSegment const *aseg = VG_(am_find_nsegment)(ARG1); 3692ef1cf8b3583107c7d918c60895937f09969d5b3esewardj NSegment const *rseg; 369365505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom 369465505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom vg_assert(aseg); 369565505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom 369665505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom if (grows == VKI_PROT_GROWSDOWN) { 36973e7986312a0ffc7646b0552d4c4ea3744a870e73florian rseg = VG_(am_next_nsegment)( aseg, False/*backwards*/ ); 369865505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom if (rseg && 369965505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom rseg->kind == SkResvn && 370065505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom rseg->smode == SmUpper && 370165505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom rseg->end+1 == aseg->start) { 370265505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom Addr end = ARG1 + ARG2; 370365505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom ARG1 = aseg->start; 370465505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom ARG2 = end - aseg->start; 370565505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom ARG3 &= ~VKI_PROT_GROWSDOWN; 370665505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } else { 370765505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom SET_STATUS_Failure( VKI_EINVAL ); 370865505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } 370965505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } else if (grows == VKI_PROT_GROWSUP) { 37103e7986312a0ffc7646b0552d4c4ea3744a870e73florian rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ ); 371165505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom if (rseg && 371265505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom rseg->kind == SkResvn && 371365505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom rseg->smode == SmLower && 371465505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom aseg->end+1 == rseg->start) { 371565505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom ARG2 = aseg->end - ARG1 + 1; 371665505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom ARG3 &= ~VKI_PROT_GROWSUP; 371765505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } else { 371865505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom SET_STATUS_Failure( VKI_EINVAL ); 371965505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } 372065505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } else { 3721337556eb91e1b42f37cd9c9c4760c4814f991a9csewardj /* both GROWSUP and GROWSDOWN */ 372265505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom SET_STATUS_Failure( VKI_EINVAL ); 372365505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } 372465505193b8d9c8f36f3df6c5d6a8e1d475bb37cbtom } 3725f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif // defined(VKI_PROT_GROWSDOWN) 3726855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3727855d93d2e9940890b28874520fa4c1677bf825e2jsgf 372885a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_mprotect) 3729855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 373022cfccb218c6975fa852a1135ddce342474b99d2njn Addr a = ARG1; 373122cfccb218c6975fa852a1135ddce342474b99d2njn SizeT len = ARG2; 373222cfccb218c6975fa852a1135ddce342474b99d2njn Int prot = ARG3; 373327ea8bc6721add61e6284cbbf684b7d06a4bd2eenethercote 3734dd3725800151572d32df10ad4df4c8aad0d3d088njn ML_(notify_core_and_tool_of_mprotect)(a, len, prot); 3735855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3736855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3737a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_munmap) 3738855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3739a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)(" munmap( %#lx )\n", ARG1); 3740a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_munmap ( %#lx, %llu )", ARG1,(ULong)ARG2); 374106c7bd748d9b40861e8a764e4947b30a787fef2bnethercote PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length); 374298abfc7bb7798c4ac4580f7e0bc7171de94a0255fitzhardinge 37437eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(valid_client_addr)(ARG1, ARG2, tid, "munmap")) 3744a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EINVAL ); 3745855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3746855d93d2e9940890b28874520fa4c1677bf825e2jsgf 374785a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_munmap) 3748855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 374922cfccb218c6975fa852a1135ddce342474b99d2njn Addr a = ARG1; 375022cfccb218c6975fa852a1135ddce342474b99d2njn SizeT len = ARG2; 375127ea8bc6721add61e6284cbbf684b7d06a4bd2eenethercote 3752ddd61ff058f02059064e083a8accaefed23d5548florian ML_(notify_core_and_tool_of_munmap)( a, len ); 3753855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3754855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3755e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_mincore) 3756e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3757a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_mincore ( %#lx, %llu, %#lx )", ARG1,(ULong)ARG2,ARG3); 3758e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "mincore", 3759e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj unsigned long, start, vki_size_t, length, 3760e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj unsigned char *, vec); 3761cdaec51384acbac00c7d88f9a54f2ee1f8f3f3e7njn PRE_MEM_WRITE( "mincore(vec)", ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE ); 3762e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 3763e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPOST(sys_mincore) 3764e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 3765cdaec51384acbac00c7d88f9a54f2ee1f8f3f3e7njn POST_MEM_WRITE( ARG3, VG_PGROUNDUP(ARG2) / VKI_PAGE_SIZE ); 3766e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 37676ceb231d84aaff064f27d38b9662750a584a189dmueller 3768a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_nanosleep) 3769855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3770a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock|SfPostOnFail; 3771a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_nanosleep ( %#lx, %#lx )", ARG1,ARG2); 37725b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote PRE_REG_READ2(long, "nanosleep", 37735b653bc2c60f6913e5bb6c2ebabfcf705a90c012nethercote struct timespec *, req, struct timespec *, rem); 377422cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_READ( "nanosleep(req)", ARG1, sizeof(struct vki_timespec) ); 377522cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != 0) 377622cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "nanosleep(rem)", ARG2, sizeof(struct vki_timespec) ); 3777855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3778855d93d2e9940890b28874520fa4c1677bf825e2jsgf 377985a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_nanosleep) 3780855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3781a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS || FAILURE); 3782ef1cf8b3583107c7d918c60895937f09969d5b3esewardj if (ARG2 != 0 && FAILURE && ERR == VKI_EINTR) 378322cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) ); 3784855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3785855d93d2e9940890b28874520fa4c1677bf825e2jsgf 3786a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_open) 3787855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 378822cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 & VKI_O_CREAT) { 3789e824cc428f6ef4a68707e99119e4ff5f1764681enethercote // 3-arg version 3790a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_open ( %#lx(%s), %ld, %ld )",ARG1,(char*)ARG1,ARG2,ARG3); 3791e824cc428f6ef4a68707e99119e4ff5f1764681enethercote PRE_REG_READ3(long, "open", 37920df495a33f39817e5cabbe94f3a5159f178d1a3anethercote const char *, filename, int, flags, int, mode); 3793e70bd7d565d58f043d07f140fd1c1b88c47899b4nethercote } else { 3794e824cc428f6ef4a68707e99119e4ff5f1764681enethercote // 2-arg version 3795a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_open ( %#lx(%s), %ld )",ARG1,(char*)ARG1,ARG2); 3796e824cc428f6ef4a68707e99119e4ff5f1764681enethercote PRE_REG_READ2(long, "open", 37970df495a33f39817e5cabbe94f3a5159f178d1a3anethercote const char *, filename, int, flags); 3798e70bd7d565d58f043d07f140fd1c1b88c47899b4nethercote } 379922cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "open(filename)", ARG1 ); 380045f4e7c91119c7d01a59f5e827c67841632c9314sewardj 38019b533f803bec4634f1106e4d4a7063d49c9694e7bart#if defined(VGO_linux) 38029b533f803bec4634f1106e4d4a7063d49c9694e7bart /* Handle the case where the open is of /proc/self/cmdline or 38039b533f803bec4634f1106e4d4a7063d49c9694e7bart /proc/<pid>/cmdline, and just give it a copy of the fd for the 38049b533f803bec4634f1106e4d4a7063d49c9694e7bart fake file we cooked up at startup (in m_main). Also, seek the 38059b533f803bec4634f1106e4d4a7063d49c9694e7bart cloned fd back to the start. */ 380670fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn { 3807f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar name[30]; // large enough 380819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* arg1s = (HChar*) ARG1; 380970fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn SysRes sres; 381070fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn 381170fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); 381270fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn if (ML_(safe_to_deref)( arg1s, 1 ) && 381370fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/cmdline")) 381470fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn ) 381570fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn { 381670fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn sres = VG_(dup)( VG_(cl_cmdline_fd) ); 381770fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn SET_STATUS_from_SysRes( sres ); 381870fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn if (!sr_isError(sres)) { 381970fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); 382070fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn if (off < 0) 382170fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn SET_STATUS_Failure( VKI_EMFILE ); 382270fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn } 382370fa47d6e19313d5f3a7b7aaae14059d98b6f1aenjn return; 382445f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 382545f4e7c91119c7d01a59f5e827c67841632c9314sewardj } 382641ad7e73914ee13bd1467ce48a1532570218e327tom 382741ad7e73914ee13bd1467ce48a1532570218e327tom /* Handle the case where the open is of /proc/self/auxv or 382841ad7e73914ee13bd1467ce48a1532570218e327tom /proc/<pid>/auxv, and just give it a copy of the fd for the 382941ad7e73914ee13bd1467ce48a1532570218e327tom fake file we cooked up at startup (in m_main). Also, seek the 383041ad7e73914ee13bd1467ce48a1532570218e327tom cloned fd back to the start. */ 383141ad7e73914ee13bd1467ce48a1532570218e327tom { 3832f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar name[30]; // large enough 383319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* arg1s = (HChar*) ARG1; 383441ad7e73914ee13bd1467ce48a1532570218e327tom SysRes sres; 383541ad7e73914ee13bd1467ce48a1532570218e327tom 383641ad7e73914ee13bd1467ce48a1532570218e327tom VG_(sprintf)(name, "/proc/%d/auxv", VG_(getpid)()); 383741ad7e73914ee13bd1467ce48a1532570218e327tom if (ML_(safe_to_deref)( arg1s, 1 ) && 383841ad7e73914ee13bd1467ce48a1532570218e327tom (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/auxv")) 383941ad7e73914ee13bd1467ce48a1532570218e327tom ) 384041ad7e73914ee13bd1467ce48a1532570218e327tom { 384141ad7e73914ee13bd1467ce48a1532570218e327tom sres = VG_(dup)( VG_(cl_auxv_fd) ); 384241ad7e73914ee13bd1467ce48a1532570218e327tom SET_STATUS_from_SysRes( sres ); 384341ad7e73914ee13bd1467ce48a1532570218e327tom if (!sr_isError(sres)) { 384441ad7e73914ee13bd1467ce48a1532570218e327tom OffT off = VG_(lseek)( sr_Res(sres), 0, VKI_SEEK_SET ); 384541ad7e73914ee13bd1467ce48a1532570218e327tom if (off < 0) 384641ad7e73914ee13bd1467ce48a1532570218e327tom SET_STATUS_Failure( VKI_EMFILE ); 384741ad7e73914ee13bd1467ce48a1532570218e327tom } 384841ad7e73914ee13bd1467ce48a1532570218e327tom return; 384941ad7e73914ee13bd1467ce48a1532570218e327tom } 385041ad7e73914ee13bd1467ce48a1532570218e327tom } 38519b533f803bec4634f1106e4d4a7063d49c9694e7bart#endif // defined(VGO_linux) 385245f4e7c91119c7d01a59f5e827c67841632c9314sewardj 385345f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* Otherwise handle normally */ 385445f4e7c91119c7d01a59f5e827c67841632c9314sewardj *flags |= SfMayBlock; 3855855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 38562f0de32c44c3e04c080fd9f6ccb1b486a954d8a7sewardj 385785a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_open) 3858855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3859a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 38607eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(RES, "open", tid, True)) { 386122cfccb218c6975fa852a1135ddce342474b99d2njn VG_(close)(RES); 3862a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EMFILE ); 3863f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 3864493dd18a6344fcb2a017a7b888d33b7fbe8b1519nethercote if (VG_(clo_track_fds)) 386519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); 3866855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3867855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 38682f0de32c44c3e04c080fd9f6ccb1b486a954d8a7sewardj 3869a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_read) 3870855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3871a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 3872a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_read ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3); 38738b76fe55a596a4296ba5028e2510015fef38b02fnethercote PRE_REG_READ3(ssize_t, "read", 3874ca0518df66f8c3375a860f1a55a51f18e2a16c44njn unsigned int, fd, char *, buf, vki_size_t, count); 3875de4a1d01951937632098a6cda45859afa587a06fsewardj 38767eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(ARG1, "read", tid, False)) 3877a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EBADF ); 387826ab77bacd7e40d93ba47632deac0403c39921b4thughes else 387922cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 ); 3880855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3881de4a1d01951937632098a6cda45859afa587a06fsewardj 388285a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_read) 3883855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3884a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 388522cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, RES ); 3886855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3887de4a1d01951937632098a6cda45859afa587a06fsewardj 3888a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_write) 3889855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 389045f4e7c91119c7d01a59f5e827c67841632c9314sewardj Bool ok; 3891a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 3892a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_write ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3); 38938b76fe55a596a4296ba5028e2510015fef38b02fnethercote PRE_REG_READ3(ssize_t, "write", 3894ca0518df66f8c3375a860f1a55a51f18e2a16c44njn unsigned int, fd, const char *, buf, vki_size_t, count); 389545f4e7c91119c7d01a59f5e827c67841632c9314sewardj /* check to see if it is allowed. If not, try for an exemption from 3896628add6061c08b1e93562bd5559e40f6d158bbb6njn --sim-hints=enable-outer (used for self hosting). */ 389745f4e7c91119c7d01a59f5e827c67841632c9314sewardj ok = ML_(fd_allowed)(ARG1, "write", tid, False); 389845f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!ok && ARG1 == 2/*stderr*/ 3899ec905f7ed1659f2251045114c785659fbb11ea88philippe && SimHintiS(SimHint_enable_outer, VG_(clo_sim_hints))) 390045f4e7c91119c7d01a59f5e827c67841632c9314sewardj ok = True; 390145f4e7c91119c7d01a59f5e827c67841632c9314sewardj if (!ok) 3902a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EBADF ); 3903855d93d2e9940890b28874520fa4c1677bf825e2jsgf else 390422cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_READ( "write(buf)", ARG2, ARG3 ); 3905855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3906de4a1d01951937632098a6cda45859afa587a06fsewardj 3907a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_creat) 3908855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3909a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 3910a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_creat ( %#lx(%s), %ld )", ARG1,(char*)ARG1,ARG2); 3911c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ2(long, "creat", const char *, pathname, int, mode); 391222cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 ); 3913855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3914de4a1d01951937632098a6cda45859afa587a06fsewardj 391585a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_creat) 3916855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3917a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 39187eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(RES, "creat", tid, True)) { 391922cfccb218c6975fa852a1135ddce342474b99d2njn VG_(close)(RES); 3920a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EMFILE ); 3921f5f536f398c082b8c92b2789a90d83b34ab98660rjwalsh } else { 3922493dd18a6344fcb2a017a7b888d33b7fbe8b1519nethercote if (VG_(clo_track_fds)) 392319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); 3924855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3925855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3926de4a1d01951937632098a6cda45859afa587a06fsewardj 3927a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_poll) 3928855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3929855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* struct pollfd { 3930ef0c7663cb71101c7b718108253444cb75402cbbnethercote int fd; -- file descriptor 3931ef0c7663cb71101c7b718108253444cb75402cbbnethercote short events; -- requested events 3932ef0c7663cb71101c7b718108253444cb75402cbbnethercote short revents; -- returned events 3933855d93d2e9940890b28874520fa4c1677bf825e2jsgf }; 3934eb0592dc023c1cbe99a2e25d3251d11aa60bec64nethercote int poll(struct pollfd *ufds, unsigned int nfds, int timeout) 3935855d93d2e9940890b28874520fa4c1677bf825e2jsgf */ 3936eb0592dc023c1cbe99a2e25d3251d11aa60bec64nethercote UInt i; 393722cfccb218c6975fa852a1135ddce342474b99d2njn struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1; 393860a4b0b77180f0c54ddca5c8d9ca20a877637f01tom *flags |= SfMayBlock; 3939a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_poll ( %#lx, %ld, %ld )\n", ARG1,ARG2,ARG3); 3940f90953e0461db3fb14e293a66a909a5d661dd0adnethercote PRE_REG_READ3(long, "poll", 3941363ec7610ee649b946edf5c1a5546b94bbf0844dtom struct vki_pollfd *, ufds, unsigned int, nfds, long, timeout); 3942363ec7610ee649b946edf5c1a5546b94bbf0844dtom 394322cfccb218c6975fa852a1135ddce342474b99d2njn for (i = 0; i < ARG2; i++) { 3944363ec7610ee649b946edf5c1a5546b94bbf0844dtom PRE_MEM_READ( "poll(ufds.fd)", 3945363ec7610ee649b946edf5c1a5546b94bbf0844dtom (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) ); 3946363ec7610ee649b946edf5c1a5546b94bbf0844dtom PRE_MEM_READ( "poll(ufds.events)", 3947363ec7610ee649b946edf5c1a5546b94bbf0844dtom (Addr)(&ufds[i].events), sizeof(ufds[i].events) ); 394868f338fbf7dd659d5377e7e0f6c6532a7f73f302tom PRE_MEM_WRITE( "poll(ufds.revents)", 3949363ec7610ee649b946edf5c1a5546b94bbf0844dtom (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) ); 3950363ec7610ee649b946edf5c1a5546b94bbf0844dtom } 3951855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3952de4a1d01951937632098a6cda45859afa587a06fsewardj 395385a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_poll) 3954855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3955416b206ee93d5e2848f66a4d86ffb654956ee2b8sewardj if (RES >= 0) { 3956855d93d2e9940890b28874520fa4c1677bf825e2jsgf UInt i; 395722cfccb218c6975fa852a1135ddce342474b99d2njn struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1; 395822cfccb218c6975fa852a1135ddce342474b99d2njn for (i = 0; i < ARG2; i++) 3959363ec7610ee649b946edf5c1a5546b94bbf0844dtom POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) ); 3960855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 3961855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 3962de4a1d01951937632098a6cda45859afa587a06fsewardj 3963a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_readlink) 3964855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 3965cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 3966cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn Word saved = SYSNO; 3967144c56d11824d3a3f7df68737b73c1b562155723sewardj 3968a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_readlink ( %#lx(%s), %#lx, %llu )", ARG1,(char*)ARG1,ARG2,(ULong)ARG3); 39695a945afbb6f858ed3a51219bb8aaf24caa07c2c5nethercote PRE_REG_READ3(long, "readlink", 39705a945afbb6f858ed3a51219bb8aaf24caa07c2c5nethercote const char *, path, char *, buf, int, bufsiz); 397122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "readlink(path)", ARG1 ); 397222cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 ); 3973de4a1d01951937632098a6cda45859afa587a06fsewardj 3974cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn { 39759b533f803bec4634f1106e4d4a7063d49c9694e7bart#if defined(VGO_linux) 3976cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn /* 3977cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn * Handle the case where readlink is looking at /proc/self/exe or 3978cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn * /proc/<pid>/exe. 3979cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn */ 3980f44ff62031a5344468774ada6f1b7375dfd85e7bflorian HChar name[30]; // large enough 398119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* arg1s = (HChar*) ARG1; 3982cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)()); 39839b533f803bec4634f1106e4d4a7063d49c9694e7bart if (ML_(safe_to_deref)(arg1s, 1) && 3984cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/exe")) 3985cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn ) 3986cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn { 3987cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd)); 3988cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, 3989cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn ARG2, ARG3)); 3990cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn } else 39919b533f803bec4634f1106e4d4a7063d49c9694e7bart#endif // defined(VGO_linux) 3992cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn { 3993cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn /* Normal case */ 3994cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3)); 3995cc1284f15c0a3fcfeec7fde68761c03d7f217f8anjn } 399617d853046a1bfc276c7dd75b7c6b2e348cdf5d24rjwalsh } 399717d853046a1bfc276c7dd75b7c6b2e348cdf5d24rjwalsh 3998a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (SUCCESS && RES > 0) 399922cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, RES ); 4000855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4001de4a1d01951937632098a6cda45859afa587a06fsewardj 4002a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_readv) 4003855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4004855d93d2e9940890b28874520fa4c1677bf825e2jsgf Int i; 400573b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_iovec * vec; 4006a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 4007a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_readv ( %ld, %#lx, %llu )",ARG1,ARG2,(ULong)ARG3); 4008d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote PRE_REG_READ3(ssize_t, "readv", 4009d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote unsigned long, fd, const struct iovec *, vector, 4010d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote unsigned long, count); 40117eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) { 4012a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EBADF ); 4013855d93d2e9940890b28874520fa4c1677bf825e2jsgf } else { 40147cbe0688bc1ac313110dee71966a5d958f8c7066florian if ((Int)ARG3 >= 0) 40157cbe0688bc1ac313110dee71966a5d958f8c7066florian PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) ); 4016d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote 401722cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != 0) { 4018d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote /* ToDo: don't do any of the following if the vector is invalid */ 401922cfccb218c6975fa852a1135ddce342474b99d2njn vec = (struct vki_iovec *)ARG2; 402022cfccb218c6975fa852a1135ddce342474b99d2njn for (i = 0; i < (Int)ARG3; i++) 4021d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote PRE_MEM_WRITE( "readv(vector[...])", 4022d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote (Addr)vec[i].iov_base, vec[i].iov_len ); 4023d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote } 4024855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4025855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4026de4a1d01951937632098a6cda45859afa587a06fsewardj 402785a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_readv) 4028855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4029a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 403022cfccb218c6975fa852a1135ddce342474b99d2njn if (RES > 0) { 4031855d93d2e9940890b28874520fa4c1677bf825e2jsgf Int i; 403222cfccb218c6975fa852a1135ddce342474b99d2njn struct vki_iovec * vec = (struct vki_iovec *)ARG2; 403322cfccb218c6975fa852a1135ddce342474b99d2njn Int remains = RES; 4034855d93d2e9940890b28874520fa4c1677bf825e2jsgf 403522cfccb218c6975fa852a1135ddce342474b99d2njn /* RES holds the number of bytes read. */ 403622cfccb218c6975fa852a1135ddce342474b99d2njn for (i = 0; i < (Int)ARG3; i++) { 4037855d93d2e9940890b28874520fa4c1677bf825e2jsgf Int nReadThisBuf = vec[i].iov_len; 4038855d93d2e9940890b28874520fa4c1677bf825e2jsgf if (nReadThisBuf > remains) nReadThisBuf = remains; 4039ef0c7663cb71101c7b718108253444cb75402cbbnethercote POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf ); 4040855d93d2e9940890b28874520fa4c1677bf825e2jsgf remains -= nReadThisBuf; 4041855d93d2e9940890b28874520fa4c1677bf825e2jsgf if (remains < 0) VG_(core_panic)("readv: remains < 0"); 4042855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4043855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4044855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4045de4a1d01951937632098a6cda45859afa587a06fsewardj 4046a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_rename) 4047855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4048cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 4049a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_rename ( %#lx(%s), %#lx(%s) )", ARG1,(char*)ARG1,ARG2,(char*)ARG2); 40509a3beb9fc89e9859ca9c3b93fa9c08ee2a2df11bnethercote PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath); 405122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 ); 405222cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 ); 4053855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4054de4a1d01951937632098a6cda45859afa587a06fsewardj 405578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_rmdir) 405678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 405778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj *flags |= SfMayBlock; 4058a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_rmdir ( %#lx(%s) )", ARG1,(char*)ARG1); 405978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ1(long, "rmdir", const char *, pathname); 406078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 ); 406178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 406278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 4063a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_select) 4064a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj{ 4065a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 4066a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_select ( %ld, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5); 4067f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote PRE_REG_READ5(long, "select", 4068f1049bfd7145c4d8ee333bb2a714700e1ab3a049nethercote int, n, vki_fd_set *, readfds, vki_fd_set *, writefds, 4069363ec7610ee649b946edf5c1a5546b94bbf0844dtom vki_fd_set *, exceptfds, struct vki_timeval *, timeout); 4070a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj // XXX: this possibly understates how much memory is read. 4071a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (ARG2 != 0) 4072a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_READ( "select(readfds)", 4073a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ARG2, ARG1/8 /* __FD_SETSIZE/8 */ ); 4074a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (ARG3 != 0) 4075a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_READ( "select(writefds)", 4076a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ARG3, ARG1/8 /* __FD_SETSIZE/8 */ ); 4077a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (ARG4 != 0) 4078a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_READ( "select(exceptfds)", 4079a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ARG4, ARG1/8 /* __FD_SETSIZE/8 */ ); 4080a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (ARG5 != 0) 408172bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_READ( "select(timeout)", ARG5 ); 4082855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4083de4a1d01951937632098a6cda45859afa587a06fsewardj 4084e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_setgid) 4085e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4086a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setgid ( %ld )", ARG1); 4087e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ1(long, "setgid", vki_gid_t, gid); 4088e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 4089696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4090696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_setsid) 4091696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4092696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRINT("sys_setsid ( )"); 4093696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ0(long, "setsid"); 4094696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4095696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4096e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_setgroups) 4097e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4098a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("setgroups ( %llu, %#lx )", (ULong)ARG1, ARG2); 4099e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list); 4100e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj if (ARG1 > 0) 4101e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) ); 4102e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 4103696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4104696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_setpgid) 4105696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4106a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("setpgid ( %ld, %ld )", ARG1, ARG2); 4107696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid); 4108696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4109696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4110696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_setregid) 4111696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4112a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setregid ( %ld, %ld )", ARG1, ARG2); 4113696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid); 4114696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4115696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4116e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_setreuid) 4117e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4118a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setreuid ( 0x%lx, 0x%lx )", ARG1, ARG2); 4119e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid); 4120e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 4121a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 4122a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_setrlimit) 4123855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4124f76d27a697a7b0bf3b84490baf60623fc96a23afnjn UWord arg1 = ARG1; 4125a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setrlimit ( %ld, %#lx )", ARG1,ARG2); 4126a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_REG_READ2(long, "setrlimit", 4127a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj unsigned int, resource, struct rlimit *, rlim); 4128a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj PRE_MEM_READ( "setrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) ); 4129de4a1d01951937632098a6cda45859afa587a06fsewardj 4130f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#ifdef _RLIMIT_POSIX_FLAG 4131f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // Darwin will sometimes set _RLIMIT_POSIX_FLAG on setrlimit calls. 4132f76d27a697a7b0bf3b84490baf60623fc96a23afnjn // Unset it here to make the if statements below work correctly. 4133f76d27a697a7b0bf3b84490baf60623fc96a23afnjn arg1 &= ~_RLIMIT_POSIX_FLAG; 4134f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif 4135f76d27a697a7b0bf3b84490baf60623fc96a23afnjn 4136db16f835c79e8f5167b4aff9ee1ddf72637ef605philippe if (!VG_(am_is_valid_for_client)(ARG2, sizeof(struct vki_rlimit), 4137db16f835c79e8f5167b4aff9ee1ddf72637ef605philippe VKI_PROT_READ)) { 4138db16f835c79e8f5167b4aff9ee1ddf72637ef605philippe SET_STATUS_Failure( VKI_EFAULT ); 4139db16f835c79e8f5167b4aff9ee1ddf72637ef605philippe } 4140db16f835c79e8f5167b4aff9ee1ddf72637ef605philippe else if (((struct vki_rlimit *)ARG2)->rlim_cur 4141db16f835c79e8f5167b4aff9ee1ddf72637ef605philippe > ((struct vki_rlimit *)ARG2)->rlim_max) { 4142aba260b91b0331551006d15f25b8576b7544d0e8tom SET_STATUS_Failure( VKI_EINVAL ); 4143aba260b91b0331551006d15f25b8576b7544d0e8tom } 4144aba260b91b0331551006d15f25b8576b7544d0e8tom else if (arg1 == VKI_RLIMIT_NOFILE) { 4145a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) || 4146a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) { 4147a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EPERM ); 4148a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4149a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj else { 4150a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur; 4151a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Success( 0 ); 4152a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4153a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4154f76d27a697a7b0bf3b84490baf60623fc96a23afnjn else if (arg1 == VKI_RLIMIT_DATA) { 4155ae0739db46c69a8eb61bcad010e14395b7e55507tom if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(client_rlimit_data).rlim_max || 4156ae0739db46c69a8eb61bcad010e14395b7e55507tom ((struct vki_rlimit *)ARG2)->rlim_max > VG_(client_rlimit_data).rlim_max) { 4157a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EPERM ); 4158a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4159a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj else { 4160a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2; 4161a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Success( 0 ); 4162a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4163a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4164f76d27a697a7b0bf3b84490baf60623fc96a23afnjn else if (arg1 == VKI_RLIMIT_STACK && tid == 1) { 4165ae0739db46c69a8eb61bcad010e14395b7e55507tom if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(client_rlimit_stack).rlim_max || 4166ae0739db46c69a8eb61bcad010e14395b7e55507tom ((struct vki_rlimit *)ARG2)->rlim_max > VG_(client_rlimit_stack).rlim_max) { 4167a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EPERM ); 4168a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4169a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj else { 4170a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur; 4171a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2; 4172a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Success( 0 ); 4173a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4174a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj } 4175855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4176de4a1d01951937632098a6cda45859afa587a06fsewardj 4177e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_setuid) 4178e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4179a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_setuid ( %ld )", ARG1); 4180e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ1(long, "setuid", vki_uid_t, uid); 4181e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 4182a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 4183696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_newstat) 4184696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4185d7aa40dc6b8f90fcd31272b83beb9c6efb25ef96philippe FUSE_COMPATIBLE_MAY_BLOCK(); 4186a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_newstat ( %#lx(%s), %#lx )", ARG1,(char*)ARG1,ARG2); 4187696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf); 4188696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 ); 4189696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) ); 4190696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4191696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4192696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_newstat) 4193696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4194696c55180aae375b48f7acc3f2aa87e13040c807sewardj POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) ); 4195696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4196696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4197696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_statfs) 4198696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4199d7aa40dc6b8f90fcd31272b83beb9c6efb25ef96philippe FUSE_COMPATIBLE_MAY_BLOCK(); 4200a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_statfs ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); 4201696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf); 4202696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_RASCIIZ( "statfs(path)", ARG1 ); 4203696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) ); 4204696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4205696c55180aae375b48f7acc3f2aa87e13040c807sewardjPOST(sys_statfs) 4206696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4207696c55180aae375b48f7acc3f2aa87e13040c807sewardj POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) ); 4208696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4209696c55180aae375b48f7acc3f2aa87e13040c807sewardj 4210e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_statfs64) 4211e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4212a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_statfs64 ( %#lx(%s), %llu, %#lx )",ARG1,(char*)ARG1,(ULong)ARG2,ARG3); 4213e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ3(long, "statfs64", 4214e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj const char *, path, vki_size_t, size, struct statfs64 *, buf); 4215e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 ); 4216e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 ); 4217e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 4218e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPOST(sys_statfs64) 4219e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4220e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj POST_MEM_WRITE( ARG3, ARG2 ); 4221e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 422278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 422378b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_symlink) 422478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 422578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj *flags |= SfMayBlock; 4226a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_symlink ( %#lx(%s), %#lx(%s) )",ARG1,(char*)ARG1,ARG2,(char*)ARG2); 422778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath); 422878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 ); 422978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 ); 423078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 4231a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 4232a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_time) 4233855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4234855d93d2e9940890b28874520fa4c1677bf825e2jsgf /* time_t time(time_t *t); */ 4235a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_time ( %#lx )",ARG1); 4236c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ1(long, "time", int *, t); 423722cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG1 != 0) { 423822cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "time(t)", ARG1, sizeof(vki_time_t) ); 4239855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4240855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4241de4a1d01951937632098a6cda45859afa587a06fsewardj 424285a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_time) 4243855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 424422cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG1 != 0) { 424522cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG1, sizeof(vki_time_t) ); 4246855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4247855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4248de4a1d01951937632098a6cda45859afa587a06fsewardj 424978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_times) 425078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 4251a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_times ( %#lx )", ARG1); 425278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ1(long, "times", struct tms *, buf); 425318f19278908d44d9d3ed0d8c318a1c6f28f7d06ftom if (ARG1 != 0) { 425418f19278908d44d9d3ed0d8c318a1c6f28f7d06ftom PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) ); 425518f19278908d44d9d3ed0d8c318a1c6f28f7d06ftom } 425678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 425778b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 425878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPOST(sys_times) 425978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 426078b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj if (ARG1 != 0) { 426178b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) ); 426278b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj } 426378b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 426478b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj 426578b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardjPRE(sys_umask) 426678b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj{ 4267a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_umask ( %ld )", ARG1); 426878b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj PRE_REG_READ1(long, "umask", int, mask); 426978b50e44c3d2a0c8c5e5d32516a03bb6903a8d1asewardj} 4270a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 4271a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_unlink) 4272a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj{ 4273a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 4274a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_unlink ( %#lx(%s) )", ARG1,(char*)ARG1); 4275c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ1(long, "unlink", const char *, pathname); 427622cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 ); 4277855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4278de4a1d01951937632098a6cda45859afa587a06fsewardj 4279a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_newuname) 4280855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4281a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_newuname ( %#lx )", ARG1); 42821a1b9b7f6ccdaf88f3fb3a69ea9a2752d7a2c726nethercote PRE_REG_READ1(long, "uname", struct new_utsname *, buf); 428322cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "uname(buf)", ARG1, sizeof(struct vki_new_utsname) ); 4284855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4285de4a1d01951937632098a6cda45859afa587a06fsewardj 428685a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_newuname) 4287855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 428822cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG1 != 0) { 428922cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG1, sizeof(struct vki_new_utsname) ); 4290855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4291855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4292de4a1d01951937632098a6cda45859afa587a06fsewardj 4293a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_waitpid) 4294855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4295a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 4296a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_waitpid ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3); 4297c6851dde1b46166417a2bdb096c05818f5f07f09nethercote PRE_REG_READ3(long, "waitpid", 4298c6851dde1b46166417a2bdb096c05818f5f07f09nethercote vki_pid_t, pid, unsigned int *, status, int, options); 4299de4a1d01951937632098a6cda45859afa587a06fsewardj 430022cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != (Addr)NULL) 430122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "waitpid(status)", ARG2, sizeof(int) ); 4302855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4303de4a1d01951937632098a6cda45859afa587a06fsewardj 430485a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_waitpid) 4305855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 430622cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != (Addr)NULL) 430722cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, sizeof(int) ); 4308855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4309de4a1d01951937632098a6cda45859afa587a06fsewardj 4310a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_wait4) 4311855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4312a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 4313a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_wait4 ( %ld, %#lx, %ld, %#lx )", ARG1,ARG2,ARG3,ARG4); 4314855d93d2e9940890b28874520fa4c1677bf825e2jsgf 43157f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote PRE_REG_READ4(long, "wait4", 43167f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote vki_pid_t, pid, unsigned int *, status, int, options, 43177f7e4d1ac0c4ea8bf771e5490b69d0e4d619dfe9nethercote struct rusage *, rusage); 431822cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != (Addr)NULL) 431922cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "wait4(status)", ARG2, sizeof(int) ); 432022cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG4 != (Addr)NULL) 432122cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "wait4(rusage)", ARG4, sizeof(struct vki_rusage) ); 4322855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4323de4a1d01951937632098a6cda45859afa587a06fsewardj 432485a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_wait4) 4325855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 432622cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != (Addr)NULL) 432722cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, sizeof(int) ); 432822cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG4 != (Addr)NULL) 432922cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) ); 4330855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4331de4a1d01951937632098a6cda45859afa587a06fsewardj 4332a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_writev) 4333855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4334855d93d2e9940890b28874520fa4c1677bf825e2jsgf Int i; 433573b526fb4af0f60634f0078583d92b931d5c0eebnethercote struct vki_iovec * vec; 4336a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 4337a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_writev ( %ld, %#lx, %llu )",ARG1,ARG2,(ULong)ARG3); 4338d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote PRE_REG_READ3(ssize_t, "writev", 4339d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote unsigned long, fd, const struct iovec *, vector, 4340d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote unsigned long, count); 43417eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj if (!ML_(fd_allowed)(ARG1, "writev", tid, False)) { 4342a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_Failure( VKI_EBADF ); 4343855d93d2e9940890b28874520fa4c1677bf825e2jsgf } else { 43447cbe0688bc1ac313110dee71966a5d958f8c7066florian if ((Int)ARG3 >= 0) 43457cbe0688bc1ac313110dee71966a5d958f8c7066florian PRE_MEM_READ( "writev(vector)", 43467cbe0688bc1ac313110dee71966a5d958f8c7066florian ARG2, ARG3 * sizeof(struct vki_iovec) ); 434722cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != 0) { 4348d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote /* ToDo: don't do any of the following if the vector is invalid */ 434922cfccb218c6975fa852a1135ddce342474b99d2njn vec = (struct vki_iovec *)ARG2; 435022cfccb218c6975fa852a1135ddce342474b99d2njn for (i = 0; i < (Int)ARG3; i++) 4351d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote PRE_MEM_READ( "writev(vector[...])", 4352d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote (Addr)vec[i].iov_base, vec[i].iov_len ); 4353d6b5a2103d0d57546d4ef9e00fb5f3a07fe0e803nethercote } 4354855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 4355855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4356de4a1d01951937632098a6cda45859afa587a06fsewardj 4357e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardjPRE(sys_utimes) 4358e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj{ 4359cc3de2dfcb3b724ecd305d9a30e9095fae6664c5sewardj FUSE_COMPATIBLE_MAY_BLOCK(); 4360a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_utimes ( %#lx(%s), %#lx )", ARG1,(char*)ARG1,ARG2); 4361e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp); 4362e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 ); 436372bbd8d24c6bd39734f465ce8d54904b6865de9bnjn if (ARG2 != 0) { 436472bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_READ( "utimes(tvp[0])", ARG2 ); 436572bbd8d24c6bd39734f465ce8d54904b6865de9bnjn PRE_timeval_READ( "utimes(tvp[1])", ARG2+sizeof(struct vki_timeval) ); 436672bbd8d24c6bd39734f465ce8d54904b6865de9bnjn } 4367e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj} 4368e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj 4369696c55180aae375b48f7acc3f2aa87e13040c807sewardjPRE(sys_acct) 4370696c55180aae375b48f7acc3f2aa87e13040c807sewardj{ 4371a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sys_acct ( %#lx(%s) )", ARG1,(char*)ARG1); 4372696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_REG_READ1(long, "acct", const char *, filename); 4373696c55180aae375b48f7acc3f2aa87e13040c807sewardj PRE_MEM_RASCIIZ( "acct(filename)", ARG1 ); 4374696c55180aae375b48f7acc3f2aa87e13040c807sewardj} 4375a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj 4376a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_pause) 4377a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj{ 4378a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj *flags |= SfMayBlock; 43790df495a33f39817e5cabbe94f3a5159f178d1a3anethercote PRINT("sys_pause ( )"); 43800df495a33f39817e5cabbe94f3a5159f178d1a3anethercote PRE_REG_READ0(long, "pause"); 4381855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4382de4a1d01951937632098a6cda45859afa587a06fsewardj 4383a8d8e239876796bc194636b8bb4b3b3c86db8528sewardjPRE(sys_sigaltstack) 4384855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4385a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart PRINT("sigaltstack ( %#lx, %#lx )",ARG1,ARG2); 4386b77dee6ad91370ba97e4aa8ba169d0b6cc18cce2nethercote PRE_REG_READ2(int, "sigaltstack", 4387b77dee6ad91370ba97e4aa8ba169d0b6cc18cce2nethercote const vki_stack_t *, ss, vki_stack_t *, oss); 438822cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG1 != 0) { 438992098dbd2b54267f92c62f70ce4050071664b590tom const vki_stack_t *ss = (vki_stack_t *)ARG1; 439092098dbd2b54267f92c62f70ce4050071664b590tom PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_sp, sizeof(ss->ss_sp) ); 439192098dbd2b54267f92c62f70ce4050071664b590tom PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_flags, sizeof(ss->ss_flags) ); 439292098dbd2b54267f92c62f70ce4050071664b590tom PRE_MEM_READ( "sigaltstack(ss)", (Addr)&ss->ss_size, sizeof(ss->ss_size) ); 4393855d93d2e9940890b28874520fa4c1677bf825e2jsgf } 439422cfccb218c6975fa852a1135ddce342474b99d2njn if (ARG2 != 0) { 439522cfccb218c6975fa852a1135ddce342474b99d2njn PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) ); 4396de4a1d01951937632098a6cda45859afa587a06fsewardj } 4397de4a1d01951937632098a6cda45859afa587a06fsewardj 4398a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj SET_STATUS_from_SysRes( 4399a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1, 4400a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj (vki_stack_t*)ARG2) 4401a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj ); 4402855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 440385a456f3640bbb4d4606f9464cd0832029e93c72nethercotePOST(sys_sigaltstack) 4404855d93d2e9940890b28874520fa4c1677bf825e2jsgf{ 4405a8d8e239876796bc194636b8bb4b3b3c86db8528sewardj vg_assert(SUCCESS); 440622cfccb218c6975fa852a1135ddce342474b99d2njn if (RES == 0 && ARG2 != 0) 440722cfccb218c6975fa852a1135ddce342474b99d2njn POST_MEM_WRITE( ARG2, sizeof(vki_stack_t)); 4408855d93d2e9940890b28874520fa4c1677bf825e2jsgf} 4409de4a1d01951937632098a6cda45859afa587a06fsewardj 4410f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtomPRE(sys_sethostname) 4411f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtom{ 4412f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtom PRINT("sys_sethostname ( %#lx, %ld )", ARG1,ARG2); 4413f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtom PRE_REG_READ2(long, "sethostname", char *, name, int, len); 4414f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtom PRE_MEM_READ( "sethostname(name)", ARG1, ARG2 ); 4415f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtom} 4416f93bbd90a4e8b5c73270f230a5d7a5fadba540bdtom 4417e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj#undef PRE 4418e6d5e72a82ba7a2c5ae243bfc226a43e43884a81sewardj#undef POST 44192e93c50dc50235189661b70e3f27a4098d5cccccsewardj 44208b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGO_linux) || defined(VGO_darwin) 44218b68b64759254d514d98328c496cbd88cde4c9a5njn 4422de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 4423c1b0181cbd6f296401daa6ff0e6e14d3a8ab91a0njn/*--- end ---*/ 4424de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/ 4425