1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- AIX5-specific syscalls.                       syswrap-aix5.c ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Copyright (C) 2006-2010 OpenWorks LLP
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      info@open-works.co.uk
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Neither the names of the U.S. Department of Energy nor the
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   University of California nor the names of its contributors may be
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   used to endorse or promote products derived from this software
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   without prior written permission.
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_aix5)
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h"
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vkiscnums.h"
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_threadstate.h"
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_aspacemgr.h"
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuginfo.h"    // VG_(di_notify_*)
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_transtab.h"     // VG_(discard_translations)
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_xarray.h"
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_clientstate.h"
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuglog.h"
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h"
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h"
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcfile.h"
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h"
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcproc.h"
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcsignal.h"
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_mallocfree.h"
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h"
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h"
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_scheduler.h"
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_signals.h"
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syscall.h"
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_sigframe.h"     // VG_(sigframe_destroy)
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syswrap.h"
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_stacktrace.h"
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_types_n_macros.h"
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_syswrap-aix5.h"
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Misc helpers
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Allocate a stack for this thread, if it doesn't already have one.
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   They're allocated lazily, and never freed.  Returns the initial stack
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pointer value to use, or 0 if allocation failed. */
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownAddr ML_(allocstack)(ThreadId tid)
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst = VG_(get_ThreadState)(tid);
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VgStack*     stack;
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr         initial_SP;
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Either the stack_base and stack_init_SP are both zero (in which
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case a stack hasn't been allocated) or they are both non-zero,
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in which case it has. */
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (tst->os_state.valgrind_stack_base == 0)
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (tst->os_state.valgrind_stack_base != 0)
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If no stack is present, allocate one. */
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (tst->os_state.valgrind_stack_base == 0) {
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      stack = VG_(am_alloc_VgStack)( &initial_SP );
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (stack) {
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Leave some space above SP because AIX's ABI stores
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            stuff there. */
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         initial_SP -= 256;
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(initial_SP > (Addr)stack);
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tst->os_state.valgrind_stack_base    = (Addr)stack;
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tst->os_state.valgrind_stack_init_SP = initial_SP;
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return 0; /* allocation of stack failed */
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0)
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)( "stack for tid %d at %p; init_SP=%p\n",
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   tid,
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (void*)tst->os_state.valgrind_stack_base,
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (void*)tst->os_state.valgrind_stack_init_SP );
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return tst->os_state.valgrind_stack_init_SP;
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If we know or believe a module load/unload event has happened, get
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   aspacem to re-read /proc/../map to update its picture of what text
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and data segments are present.  This also notifies all the usual
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parties that need to know about address space changes. */
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(aix5_rescan_procmap_after_load_or_unload) ( void )
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AixCodeSegChange* changes;
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int changes_size, changes_used, i;
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Find out how many AixCodeSegChange records we will need, and
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      acquire them. */
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   changes = VG_(arena_malloc)(VG_AR_CORE, "syswrap-aix5.arpalou.1",
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               changes_size * sizeof(AixCodeSegChange));
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(changes);
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now re-read /proc/<pid>/map and acquire a change set */
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(am_aix5_reread_procmap)( changes, &changes_used );
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(changes_used >= 0 && changes_used <= changes_size);
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* And notify all parties of the changes. */
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < changes_used; i++) {
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ULong di_handle = VG_(di_aix5_notify_segchange)(
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].code_start,
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].code_len,
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].data_start,
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].data_len,
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].file_name,
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].mem_name,
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].is_mainexe,
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           changes[i].acquire
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        );
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (changes[i].acquire) {
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_TRACK( new_mem_mmap,
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   changes[i].code_start, changes[i].code_len,
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   /*r*/True, /*w*/False, /*x*/True, di_handle );
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_TRACK( new_mem_mmap,
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   changes[i].data_start, changes[i].data_len,
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   /*r*/True, /*w*/True, /*x*/False, 0/*or di_handle?*/ );
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_TRACK( die_mem_munmap,
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   changes[i].code_start, changes[i].code_len );
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_TRACK( die_mem_munmap,
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   changes[i].data_start, changes[i].data_len );
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(discard_translations)(
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   changes[i].code_start, changes[i].code_len,
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "POST(sys___loadx/sys__kload)(code)" );
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(discard_translations)(
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    changes[i].data_start, changes[i].data_len,
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   "POST(sys___loadx/sys__kload)(data)" );
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(arena_free)(VG_AR_CORE, changes);
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Mess with the given thread's pc/toc so that it is entering
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_exit() with argument PTHREAD_CANCELED.  Returns True if ok,
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   False if it failed to do so, due to not being able to find
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_exit() by searching symbol tables. */
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool ML_(aix5_force_thread_into_pthread_exit)( ThreadId tid )
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr ent = 0, toc = 0;
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool found;
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst = VG_(get_ThreadState)(tid);
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   found = VG_(lookup_symbol_SLOW)("libpthread*.a(*.o)", "pthread_exit",
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   &ent, &toc);
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (found) {
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0)
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("THREAD CANCELED, new cia,toc = %#lx,%#lx\n", ent, toc);
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->arch.vex.guest_CIA  = ent;
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->arch.vex.guest_GPR2 = toc;
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->arch.vex.guest_GPR3 = (Word)(-1); /* == PTHREAD_CANCELED */
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If the thread is blocked in a syscall, we better bop it on
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the head with SIGVGKILL in order to get it out of said
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         syscall. */
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (tst->status == VgTs_WaitSys) {
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (VG_(clo_trace_syscalls))
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("(sending SIGVGKILL to tid %d)", (Int)tid);
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(get_thread_out_of_syscall)( tid  );
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return True; /* ok */
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // urk.  Now we're hosed.  Let the caller figure out what to do.
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return False; /* failed */
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* For various reasons, on AIX we may have to just give up if
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   continuing is too difficult (eg, risk of future deadlock).  This
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sets up the process state to exit straight away, but does not
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   actually itself exit. */
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(aix5_set_threadstate_for_emergency_exit)(ThreadId tid, HChar* why)
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst = VG_(get_ThreadState)(tid);
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Set the thread's status to be exiting and taking out the
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      entire process, then claim that the syscall succeeded. */
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->exitreason = VgSrc_ExitProcess;
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.exitcode = 1;
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!VG_(clo_xml)) {
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(message)(Vg_UserMsg,
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "WARNING: AIX: %s\n", why);
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(message)(Vg_UserMsg,
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "WARNING: (too difficult to continue past this point).\n");
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(get_and_pp_StackTrace)(tid, 10);
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Update aspacem etc on conclusion of a successful sbrk/__libc_sbrk
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   call.  2006-08-24: this was not completed because I don't
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   understand what sbrk/__libc_sbrk are doing. */
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void handle_sbrk ( Word delta )
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (delta > 0) {
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Map in VG_(brk_limit) for delta */
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* using notify_mmap ? */
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(brk_limit) += delta;
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (delta < 0) {
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Addr tmp = VG_(brk_limit);
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(brk_limit) += delta;
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     /* Can't move below original starting point */
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     if (VG_(brk_limit) < VG_(brk_base))
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        VG_(brk_limit) = VG_(brk_base);
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     if (VG_(brk_limit) < tmp)
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        /* Unmap VG_(brk_limit) for tmp - VG_(brk_limit) */
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        /* using notify_munmap ? */
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        ;
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_trace_syscalls))
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("new brk: 0x%010llx-0x%010llx (size %lld)\n",
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (ULong)VG_(brk_base),
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (ULong)VG_(brk_limit),
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (ULong)VG_(brk_limit) - (ULong)VG_(brk_base));
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/thread.h>
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/poll.h>
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/times.h>
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/shm.h>
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <semaphore.h>
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/statfs.h>
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/utsname.h>
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownHChar* ML_(aix5debugstuff_pc_to_fnname) ( Addr pc )
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ok;
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static HChar name[100];
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ok = VG_(get_fnname_w_offset)(pc, name, 100);
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ok) VG_(strcpy)(name, "???");
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return &name[0];
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void aix5debugstuff_show_sigset ( vki_sigset_t* set )
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  Int i;
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  UChar* p = (UChar*)set;
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < sizeof(vki_sigset_t); i++)
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(printf)("%02x", (Int)p[i]);
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic HChar* aix5debugstuff_name_of_tstate_flag ( UWord flag )
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i, nset;
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nset = 0;
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 8*sizeof(UWord); i++)
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (flag & (1U << i))
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nset++;
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(nset == 1);
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (flag) {
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_LOCAL:           return "LOCAL";
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CANCEL_DEFER:    return "CANCEL_DEFER";
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CANCEL_DISABLE:  return "CANCEL_DISABLE";
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CANCEL_PENDING:  return "CANCEL_PENDING";
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CANCEL_CHKPT:    return "CANCEL_CHKPT";
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_INTR:            return "INTR";
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_EXEMPT:          return "EXEMPT";
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_PROFILING_OFF
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_PROFILING_OFF:   return "PROFILING_OFF";
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_SUSPEND:         return "SUSPEND";
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CONT:            return "CONT";
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_CREDS
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CREDS:           return "CREDS";
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_PROCHANDLERS
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_PROCHANDLERS:    return "PROCHANDLERS";
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_ADVH:            return "ADVH";
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_SYNCH:           return "SYNCH";
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_USCHED:          return "USCHED";
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_DEFAULT_SCHED:   return "DEFAULT_SCHED";
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_INHERIT_SCHED
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_INHERIT_SCHED:   return "INHERIT_SCHED";
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_LOCAL_INIT
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_LOCAL_INIT:      return "LOCAL_INIT";
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_LOCAL_TERM
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_LOCAL_TERM:      return "LOCAL_TERM";
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_LOCAL_MCHANGE
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_LOCAL_MCHANGE:   return "LOCAL_MCHANGE";
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_ALL:      return "CHANGE_ALL";
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_CHANGE_PTID
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_PTID:     return "CHANGE_PTID";
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_CHANGE_PROFILE
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_PROFILE:  return "CHANGE_PROFILE";
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef TSTATE_CHANGE_SSTACK
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_SSTACK:   return "CHANGE_SSTACK";
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_ERRNOP:   return "CHANGE_ERRNOP";
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_SIGMASK:  return "CHANGE_SIGMASK";
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_PSIG:     return "CHANGE_PSIG";
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_SCHED:    return "CHANGE_SCHED";
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_FLAGS:    return "CHANGE_FLAGS";
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case TSTATE_CHANGE_USERDATA: return "CHANGE_USERDATA";
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: return "???";
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(aix5debugstuff_show_tstate_flags) ( UWord w )
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const Int step = 5;
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i, j;
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord m;
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   j = 0;
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 8*sizeof(UWord); i++) {
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      m = 1U << i;
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((w & m) == 0)
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((j % step) == 0)
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("  ");
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("%s ", aix5debugstuff_name_of_tstate_flag(w & m));
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((j % step) == step-1 && j > 0)
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("\n");
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      j++;
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (((j-1) % step) != step-1 && j > 0)
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n");
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(aix5debugstuff_show_tstate) ( Addr tsA, HChar* who )
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i;
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   const Int step = sizeof(void*)==8  ? 3 : 5;
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct tstate* ts = (struct tstate*)tsA;
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n{ ========= %s =========\n", who);
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < _NGPRS; i++) {
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((i % step) == 0)
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("  [%2d]  ", i);
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (sizeof(void*)==8)
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("%016llx  ", (ULong)ts->mst.gpr[i]);
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("%08llx  ", (ULong)ts->mst.gpr[i]);
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((i == _NGPRS-1) || ((i % step) == step-1 && i > 0))
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("\n");
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  [iar] %#llx %s\n", (ULong)ts->mst.iar,
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               ML_(aix5debugstuff_pc_to_fnname)(ts->mst.iar));
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  errnop_addr      %p\n", ts->errnop_addr);
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  sigmask          ");
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   aix5debugstuff_show_sigset( (vki_sigset_t*)&ts->sigmask );
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n");
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  psig             ");
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   aix5debugstuff_show_sigset( (vki_sigset_t*)&ts->psig );
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n");
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  policy           %d\n", ts->policy);
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  priority         %d\n", ts->priority);
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  flags            0x%x\n", ts->flags);
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(aix5debugstuff_show_tstate_flags)( (UWord)ts->flags );
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  flagmask         0x%x\n", ts->flagmask);
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  userdata         %p\n", (void*)ts->userdata);
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  fpinfo           %d\n", ts->fpinfo);
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  fpscrx           %d\n", ts->fpscrx);
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  sigaltstack      ??\n");
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  thread_control_p 0x%llx\n", (ULong)ts->thread_control_p);
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   AIX 5.1 does not seem to have these members
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   VG_(printf)("  prbase           %p\n", (void*)ts->prbase);
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   VG_(printf)("  credp            %p\n", (void*)ts->credp);
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   VG_(printf)("  ptid             %d\n", (int)ts->ptid);
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//   VG_(printf)("  tct_clock        %d\n", (int)ts->tct_clock);
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)tsA;
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < sizeof(struct tstate)/sizeof(UInt); i++) {
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HChar* s = ML_(aix5debugstuff_pc_to_fnname)( (Addr)p[i] );
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0==VG_(strcmp)(s,"???"))
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("  [%d] %x %s\n", i, p[i], s);
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("}\n");
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE/POST wrappers for arch-generic, AIX5-specific syscalls.  Note:
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in fact AIX5 doesn't share any wrappers with Linux since it's
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   difficult to get syswrap-generic.c to compile on AIX.  Hence in
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fact this file also serves the role of syswrap-generic.c for AIX.
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This could probably be improved at the cost of some extra effort.
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Nb: See the comment above the generic PRE/POST wrappers in
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// m_syswrap/syswrap-generic.c for notes about how they work.
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE(name)       DEFN_PRE_TEMPLATE(aix5, name)
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST(name)      DEFN_POST_TEMPLATE(aix5, name)
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// How to make __libc_sbrk appear to fail, from libc's point of view:
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//  SysRes r;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//  r.res = -1; /* significant to libc */
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//  r.err = VKI_ENOMEM; /* not significant to libc */
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//  SET_STATUS_from_SysRes( r );
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//  return;
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys___libc_sbrk)
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__libc_sbrk (BOGUS HANDLER)( %#lx )",ARG1);
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "__libc_sbrk", long, arg1);
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* After a zero sbrk, disallow aspacem from doing sbrk, since libc
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      might rely on the value returned by this syscall. */
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* 1 Oct 06: not currently used (aspacemgr-aix5.c ignores it) */
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(am_aix5_sbrk_allowed) = toBool(ARG1 != 0);
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Disallow libc from moving the brk backwards as that might trash
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SkPreAlloc sections acquired by aspacem from previous uses of
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sbrk. */
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 < 0)
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1 = 0;
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Do this as a sync syscall, so the sbrk_allowed flag gets turned
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      back on ASAP.  Typically libc does sbrk(0) and then sbrk(x > 0)
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in quick succession.  Although surely it should hold some kind
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of lock at that point, else it cannot safely use the result from
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the first sbrk call to influence the second one? */
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys___libc_sbrk)
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   handle_sbrk(ARG1);
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* __loadx is handled in the platform-specific files. */
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys___msleep)
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("__msleep (BOGUS HANDLER) ( %#lx )", ARG1);
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "msleep", void*, arg1);
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* __unload is handled in the platform-specific files. */
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__clock_settime)
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_clock_settime (UNDOCUMENTED) ( %ld, %#lx )", ARG1, ARG2);
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "_clock_settime", int, arg1, int, arg2);
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__exit)
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst;
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* simple; just make this thread exit */
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_exit( %ld )", ARG1);
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "exit", int, exitcode);
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst = VG_(get_ThreadState)(tid);
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Set the thread's status to be exiting and taking out the entire
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      process, then claim that the syscall succeeded. */
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->exitreason = VgSrc_ExitProcess;
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.exitcode = ARG1;
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Success(0);
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__fp_fpscrx_sc)
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_fp_fpscrx_sc (BOGUS HANDLER)");
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__getpgrp)
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_getpgrp (BOGUS HANDLER)");
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__getpid)
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_getpid ( )");
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__getppid)
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_getppid ( )");
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__getpriority)
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_getpriority (BOGUS HANDLER)");
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__nsleep)
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_nsleep( %#lx, %#lx )", ARG1, ARG2);
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(void, "_nsleep", struct timestruc_t*, arg1,
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  struct timestruc_t*, arg2);
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* In 64-bit mode, struct ends in 4 padding bytes.  Hence: */
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1)
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ("_nsleep(arg1)",
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   ARG1,
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   sizeof(void*)==4 ? sizeof(struct timestruc_t)
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    : sizeof(struct timestruc_t)-4 );
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2)
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE("_nsleep(arg2)", ARG2, sizeof(struct timestruc_t));
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys__nsleep)
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2)
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG2, sizeof(struct timestruc_t));
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__pause)
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  *flags |= SfMayBlock;
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRINT("_pause ( )");
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_REG_READ0(long, "pause");
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__poll)
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt i;
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct pollfd* ufds = (struct pollfd *)ARG1;
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_poll ( %#lx, %ld, %ld )\n", ARG1,ARG2,ARG3);
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "_poll",
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < ARG2; i++) {
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "poll(ufds.fd)",
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "poll(ufds.events)",
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "poll(ufds.reventss)",
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys__poll)
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES > 0) {
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt i;
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct pollfd* ufds = (struct pollfd *)ARG1;
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < ARG2; i++)
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__select)
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt nfds, nmqids;
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* XXX: copy of generic; I don't know if this is right or not. */
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_select ( %ld, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(long, "_select",
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, n, struct sellist *, readfds,
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         struct sellist *, writefds,
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         struct sellist *, exceptfds,
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         struct timeval *, timeout);
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nfds   = ((UInt)ARG1) & 0xFFFF;
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nmqids = (((UInt)ARG1) >> 16) & 0xFFFF;
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // XXX: this possibly understates how much memory is read.
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 != 0)
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PRE_MEM_READ( "select(readfds)",
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   ARG2, nfds/8 /* __FD_SETSIZE/8 */ );
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 != 0)
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PRE_MEM_READ( "select(writefds)",
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   ARG3, nfds/8 /* __FD_SETSIZE/8 */ );
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG4 != 0)
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PRE_MEM_READ( "select(exceptfds)",
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown		   ARG4, nfds/8 /* __FD_SETSIZE/8 */ );
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5 != 0)
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     PRE_MEM_READ( "select(timeout)", ARG5,
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   /* in 64-bit mode, struct timeval has 4 bytes of
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      padding at the end, which tend to not be
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      initialised. */
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   sizeof(void*)==4  ? sizeof(struct timeval)
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     : sizeof(struct timeval)-4
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     );
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__sem_wait)
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_sem_wait (BOGUS HANDLER) ( %#lx, %#lx, %ld )", ARG1, ARG2, ARG3);
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "_sem_wait", void*, arg1, void*, arg2, long, arg3 );
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Not sure what the two pointer args are.  Hence no proper handler.*/
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__setpgid)
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setpgid ( %ld, %ld )", ARG1, ARG2);
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "setpgid", int, pid, int, pgid);
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__setsid)
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setsid ( )");
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__sigaction) /* COL, more or less */
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_sigaction ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "_sigaction",
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, signum, const struct sigaction *, act,
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 struct sigaction *, oldact);
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 != 0) {
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct vki_sigaction *sa = (struct vki_sigaction *)ARG2;
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "_sigaction(act->sa_handler)",
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "_sigaction(act->sa_mask)",
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "rt_sigaction(act->sa_flags)",
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 != 0)
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  (struct vki_sigaction *)ARG3)
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys__sigaction)
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES == 0 && ARG3 != 0)
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__thread_self)
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_thread_self ( )");
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys__thread_setsched)
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("_thread_setsched ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "_thread_setsched", long, arg1, long, arg2, long, arg3);
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_access)
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("access ( %#lx(%s), %ld )", ARG1,(Char*)ARG1, ARG2);
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "access", char*, pathname, int, mode);
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_accessx)
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("accessx ( %#lx(%s), %ld, %ld )", ARG1,(Char*)ARG1, ARG2, ARG3);
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "accessx", char*, pathname, int, mode, int, who);
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "accessx(pathname)", ARG1 );
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_appgetrlimit)
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Note: assumes kernel struct == libc struct */
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("appgetrlimit ( %ld, %#lx )", ARG1, ARG2);
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "appgetrlimit", int, arg1, struct rlimit*, arg2);
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "appgetrlimit(buf)", ARG2, sizeof(struct rlimit) );
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_appgetrlimit)
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct rlimit) );
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_appgetrusage)
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Note: assumes kernel struct == libc struct */
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("appgetrusage ( %ld, %#lx )", ARG1, ARG2);
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "appgetrusage", int, arg1, struct rusage*, arg2);
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "appgetrusage(buf)", ARG2, sizeof(struct rusage) );
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_appgetrusage)
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct rusage) );
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_apprestimer)
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("apprestimer (BOGUS HANDLER)");
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_appsetrlimit)
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("appsetrlimit (BOGUS HANDLER)");
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_appulimit)
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("appulimit ( %ld, %ld )", ARG1, ARG2);
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "appulimit", long, arg1, long, arg2);
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_bind)
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("bind ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "bind", int, socket,
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              void*, address, int, addresslen);
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Hmm.  This isn't really right - see pre_mem_read_sockaddr. */
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "bind(address)", ARG2, ARG3 );
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_chdir)
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRINT("chdir ( %#lx(%s) )", ARG1,(Char*)ARG1);
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_REG_READ1(long, "chdir", const char *, path);
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_chmod)
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("chmod ( %#lx(%s), 0x%lx )", ARG1,(Char*)ARG1, ARG2 );
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "chmod", char*, path, int, mode);
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_chown)
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("chown ( %#lx(%s), %ld, %ld )", ARG1,(Char*)ARG1, ARG2, ARG3 );
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "chown", char*, path, int, owner, int, group);
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_close)
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("close ( %ld )", ARG1);
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "close", UInt, fd);
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If doing -d style logging (which is to fd=2), don't allow that
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      to be closed. */
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EBADF );
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_connext)
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* apparently undocumented.  I don't know what it does. */
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Although /usr/include/net/proto_uipc.h does mention it.
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Args are apparently (int, caddr_t, int).  I suspect the
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      first arg is a fd and the third a flags value. */
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("connext (UNDOCUMENTED)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "connext", int, arg1, caddr_t*, arg2, int, arg3);
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//--- PRE(sys_execve) ---//
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Pre_read a char** argument.
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr a_deref;
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr* a_p = (Addr*)a;
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a_deref = *a_p;
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0 == a_deref)
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_RASCIIZ( s2, a_deref );
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a += sizeof(char*);
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic SysRes simple_pre_exec_check ( const HChar* exe_name,
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                      Bool trace_this_child )
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int fd, ret;
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes res;
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool setuid_allowed;
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check it's readable
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   res = VG_(open)(exe_name, VKI_O_RDONLY, 0);
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (res.isError) {
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return res;
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fd = res.res;
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(close)(fd);
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Check we have execute permissions.  We allow setuid executables
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // to be run only in the case when we are not simulating them, that
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // is, they to be run natively.
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   setuid_allowed = trace_this_child  ? False  : True;
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ret = VG_(check_executable)(NULL/*&is_setuid*/,
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                               (HChar*)exe_name, setuid_allowed);
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0 != ret) {
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return VG_(mk_SysRes_Error)(ret);
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return VG_(mk_SysRes_Success)(0);
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_execve)
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char*        path = NULL;       /* path to executable */
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char**       envp = NULL;
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char**       argv = NULL;
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char**       arg2copy;
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Char*        launcher_basename = NULL;
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst;
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int          i, j, tot_args;
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes       res;
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool         trace_this_child;
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )", ARG1, (Char*)ARG1, ARG2, ARG3);
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(vki_off_t, "execve",
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 char *, filename, char **, argv, char **, envp);
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 != 0)
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 != 0)
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(VG_(is_valid_tid)(tid));
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst = VG_(get_ThreadState)(tid);
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Erk.  If the exec fails, then the following will have made a
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      mess of things which makes it hard for us to continue.  The
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      right thing to do is piece everything together again in
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST(execve), but that's close to impossible.  Instead, we make
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      an effort to check that the execve will work before actually
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      doing it. */
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check that the name at least begins in client-accessible storage. */
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* XXX: causes execve to fail for non-memcheck tools, presumably
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      because ARG1 is thought to not to being in client-accessible
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      storage due to inadequate address space tracking.  May or may
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      not be due to non-tracking of brk. */
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   SET_STATUS_Failure( VKI_EFAULT );
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //   return;
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //}
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 == 0 /* obviously bogus */) {
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_EFAULT );
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Decide whether or not we want to follow along
872f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov   trace_this_child = VG_(should_we_trace_this_child)( (HChar**)ARG2 );
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Do the important checks:  it is a file, is executable, permissions are
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // ok, etc.
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   res = simple_pre_exec_check( (const HChar*)ARG1, trace_this_child );
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (res.isError) {
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( res.err );
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If we're tracing the child, and the launcher name looks bogus
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (possibly because launcher.c couldn't figure it out, see
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      comments therein) then we have no option but to fail. */
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (trace_this_child
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       && (VG_(name_of_launcher) == NULL
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           || VG_(name_of_launcher)[0] != '/')) {
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* After this point, we can't recover if the execve fails. */
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(debugLog)(1, "syswrap", "Exec of %s\n", (Char*)ARG1);
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Resistance is futile.  Nuke all other threads.  POSIX mandates
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this. (Really, nuke them all, since the new process will make
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      its own new thread.) */
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(reap_threads)(tid);
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Set up the child's exe path.
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (trace_this_child) {
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // We want to exec the launcher.  Get its pre-remembered path.
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      path = VG_(name_of_launcher);
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // VG_(name_of_launcher) should have been acquired by m_main at
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // startup.
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(path);
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      launcher_basename = VG_(strrchr)(path, '/');
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (launcher_basename == NULL || launcher_basename[1] == 0) {
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         launcher_basename = path;  // hmm, tres dubious
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         launcher_basename++;
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      path = (Char*)ARG1;
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Set up the child's environment.
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Remove the valgrind-specific stuff from the environment so the
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // This is done unconditionally, since if we are tracing the child,
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // the child valgrind will set up the appropriate client environment.
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Nb: we make a copy of the environment before trying to mangle it
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // as it might be in read-only memory (this was bug #101881).
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Then, if tracing the child, set VALGRIND_LIB for it.
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 == 0) {
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      envp = NULL;
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      envp = VG_(env_clone)( (Char**)ARG3 );
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (envp == NULL) goto hosed;
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(env_remove_valgrind_env_stuff)( envp );
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (trace_this_child) {
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // Set VALGRIND_LIB in ARG3 (the environment)
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Set up the child's args.  If not tracing it, they are
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // simply ARG2.  Otherwise, they are
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG2[1..]
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // except that the first VG_(args_for_valgrind_noexecpass) args
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // are omitted.
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!trace_this_child) {
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv = (Char**)ARG2;
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert( VG_(args_for_valgrind_noexecpass)
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* how many args in total will there be? */
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // launcher basename
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args = 1;
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // V's args
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args -= VG_(args_for_valgrind_noexecpass);
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // name of client exe
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tot_args++;
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // args for client exe, skipping [0]
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      arg2copy = (Char**)ARG2;
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (arg2copy && arg2copy[0]) {
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 1; arg2copy[i]; i++)
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            tot_args++;
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // allocate
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv = VG_(malloc)( "syswrap-aix5.pre_sys_execve.1",
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          (tot_args+1) * sizeof(HChar*) );
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (argv == 0) goto hosed;
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // copy
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      j = 0;
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv[j++] = launcher_basename;
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (i < VG_(args_for_valgrind_noexecpass))
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            continue;
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv[j++] = (Char*)ARG1;
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (arg2copy && arg2copy[0])
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 1; arg2copy[i]; i++)
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            argv[j++] = arg2copy[i];
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      argv[j++] = NULL;
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // check
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(j == tot_args+1);
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* restore the DATA rlimit for the child */
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Set the signal state up for exec.
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      We need to set the real signal state to make sure the exec'd
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      process gets SIG_IGN properly.
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Also set our real sigmask to match the client's sigmask so that
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the exec'd child will get the right mask.  First we need to
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      clear out any pending signals so they they don't get delivered,
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      which would confuse things.
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX This is a bug - the signals should remain pending, and be
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      delivered to the new process after exec.  There's also a
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      race-condition, since if someone delivers us a signal between
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the sigprocmask and the execve, we'll still get the signal. Oh
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      well.
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   {
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_sigset_t allsigs;
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_siginfo_t info;
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 1; i < VG_(max_signal); i++) {
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct vki_sigaction sa;
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(do_sys_sigaction)(i, NULL, &sa);
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (sa.ksa_handler == VKI_SIG_IGN)
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(sigaction)(i, &sa, NULL);
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else {
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            sa.ksa_handler = VKI_SIG_DFL;
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(sigaction)(i, &sa, NULL);
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(sigfillset)(&allsigs);
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ;
1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) {
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Char **cpp;
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("exec: %s\n", path);
1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (cpp = argv; cpp && *cpp; cpp++)
1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("argv: %s\n", *cpp);
1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0)
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (cpp = envp; cpp && *cpp; cpp++)
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("env: %s\n", *cpp);
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp)
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If we got here, then the execve failed.  We've already made way
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      too much of a mess to continue, so we have to abort. */
1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  hosed:
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(FAILURE);
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld\n",
1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ARG1, (Char*)ARG1, ARG2, ARG3, ERR);
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "execve() failing, so I'm dying.\n");
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "or work out how to recover.\n");
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(exit)(101);
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_finfo)
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("finfo ( %#lx(%s), %ld, %#lx, %ld )",
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          ARG1,(Char*)ARG1, ARG2, ARG3, ARG4);
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "finfo",
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      char*, Path1, int, cmd, void*, buffer, int, length);
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "finfo(Path1)", ARG1 );
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "finfo(buffer)", ARG3, ARG4 );
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_finfo)
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG3, ARG4 );
1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_fstatfs)
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_fstatfs ( %ld, %#lx )", ARG1, ARG2);
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(UWord, "fstatfs", UWord, fd, struct statfs *, buf);
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct statfs) );
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_fstatfs)
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_fstatx)
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fstatx ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4 );
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(Word, "fstatx", UWord, fd, void*, buf,
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 UWord, len, UWord, cmd);
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "fstatx(buf)", ARG2, ARG3 );
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_fstatx)
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, ARG3 );
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_fsync)
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("fsync ( %ld )", ARG1);
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "fsync", int, fd);
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getdirent)
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* this is pretty much like 'read':
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      getdirent(fd, buffer, nbytes) -> # actually read */
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdirent ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(Word, "getdirent", UWord, fd, UChar*, buf, UWord, count);
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "getdirent(buf)", ARG2, ARG3 );
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getdirent)
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, RES );
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getdirent64)
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* same as getdirent, from our point of view? */
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* this is pretty much like 'read':
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      getdirent(fd, buffer, nbytes) -> # actually read */
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdirent64 ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(Word, "getdirent64", UWord, fd, UChar*, buf, UWord, count);
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "getdirent64(buf)", ARG2, ARG3 );
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getdirent64)
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, RES );
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getdomainname)
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getdomainname ( %#lx, %ld )", ARG1, ARG2 );
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "getdomainname(buf)", ARG1, ARG2 );
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getdomainname)
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG1, ARG2 );
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getgidx)
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getgidx ( %ld )", ARG1);
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(UInt, "getgidx", long, arg1);
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getgroups)
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getgroups ( %ld, %#lx )", ARG1, ARG2);
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "getgroups", int, size, gid_t *, list);
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 > 0)
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(gid_t) );
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getgroups)
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 > 0 && RES > 0)
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG2, RES * sizeof(gid_t) );
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_gethostname)
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("gethostname ( %#lx, %ld )", ARG1, ARG2);
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "gethostname(buf)", ARG1, ARG2 );
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_gethostname)
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG1, ARG2 );
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getpriv)
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getpriv (UNDOCUMENTED)(%ld, %#lx, %ld)", ARG1, ARG2, ARG3);
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "getpriv", int, arg1, void*, arg2, int, arg3);
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "getpriv(arg2)", ARG2, 8 );
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getpriv)
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2)
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG2, 8);
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Note that this is used for both sys_getprocs and sys_getprocs64.  I
1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   think that's correct - from the man page, the calling conventions
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   look identical. */
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getprocs)
1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getprocs ( %#lx, %ld, %#lx, %ld, %#lx, %ld )",
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(int, "getprocs",
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, processbuffer, long, processize,
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, filebuffer, long, filesize,
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, indexpointer, long, count);
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* (processbuffer, processsize, filebuffer, filesize,
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      indexpointer, count) */
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "getprocs(IndexPointer)", ARG5, sizeof(UInt) );
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1)
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "getprocs(ProcessBuffer)", ARG1, ARG2 * ARG6 );
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3)
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "getprocs(FileBuffer)", ARG3, ARG4 * ARG6 );
1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getprocs)
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1)
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG1, ARG2 * ARG6 );
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3)
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, ARG4 * ARG6 );
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getrpid)
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getrpid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "getrpid", long, arg1, long, arg2, long, arg3);
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getsockopt)
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5);
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(int, "getsockopt", int, socket, int, level,
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    int, optionname,
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    void*, optionval, int*, optionlen);
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "getsockopt(optionlen)", ARG5, sizeof(UInt) );
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "getsockopt(optionval)", ARG4, *(UInt*)ARG5 );
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_getsockopt)
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG5, sizeof(UInt) );
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG4, *(UInt*)ARG5 );
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_gettimerid)
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("gettimerid ( %ld, %ld )", ARG1, ARG2);
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "gettimerid", int, timertype, int, notifytype);
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_getuidx)
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("getuidx ( %ld )", ARG1);
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(UInt, "getuidx", UInt, arg1);
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_incinterval)
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("incinterval ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "incinterval", int, timerid,
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      struct itimerstruc_t*, value,
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      struct itimerstruc_t*, ovalue);
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2)
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "incinterval(value)",
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ARG2, sizeof(struct itimerstruc_t));
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3)
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "incinterval(value)",
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ARG3, sizeof(struct itimerstruc_t));
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_incinterval)
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3)
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct itimerstruc_t));
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kfcntl)
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2) {
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // These ones ignore ARG3.
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_GETFD:
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_GETFL:
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_GETOWN:
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("kfcntl ( %ld, %ld )", ARG1,ARG2);
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // These ones use ARG3 as "arg".
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_DUPFD:
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETFD:
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETFL:
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETOWN:
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("kfcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_REG_READ3(long, "fcntl",
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // These ones use ARG3 as "lock".
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     if !defined(VGP_ppc64_aix5)
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_GETLK:
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETLK:
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETLKW:
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     endif
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_GETLK64:
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETLK64:
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case F_SETLKW64:
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRINT("kfcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         PRE_REG_READ3(long, "fcntl",
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       unsigned int, fd, unsigned int, cmd,
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct flock64 *, lock);
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ARG3 && (ARG2 == F_GETLK || ARG2 == F_GETLK64))
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRE_MEM_READ( "kfcntl(F_GETLK)", ARG3, sizeof(struct flock64) );
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_kfcntl)
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //  if (ARG2 == VKI_F_DUPFD) {
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //   if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //    VG_(close)(RES);
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //    SET_STATUS_Failure( VKI_EMFILE );
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //  } else {
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //    if (VG_(clo_track_fds))
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //	record_fd_open_named(tid, RES);
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //  }
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  // }
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 && (ARG2 == F_GETLK || ARG2 == F_GETLK64))
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct flock64) );
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* COG; can this be moved inside the pre-handler? */
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic vki_sigset_t fork_saved_mask;
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kfork) /* COPY OF GENERIC */
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vki_sigset_t mask;
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kfork ( )");
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ0(long, "fork");
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Block all signals during fork, so that we can fix things up in
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the child without being interrupted. */
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sigfillset)(&mask);
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(do_atfork_pre)(tid);
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (SUCCESS && RES == 0) {
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* child */
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_atfork_child)(tid);
1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* restore signal mask */
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If --child-silent-after-fork=yes was specified, set the
1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         logging file descriptor to an 'impossible' value.  This is
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         noticed by send_bytes_to_logging_sink in m_libcprint.c, which
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         duly stops writing any further logging output. */
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork))
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(clo_log_fd) = -1;
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (SUCCESS && RES > 0) {
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* parent */
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_atfork_parent)(tid);
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("   fork: process %d created child %lu\n", VG_(getpid)(), RES);
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* restore signal mask */
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kftruncate)
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kftruncate (BOGUS HANDLER)");
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kgetsidx)
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kgetsidx ( %ld )", ARG1);
1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(Word, "kgetsidx", Word, arg1);
1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kill)
1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kill ( %ld, %ld )", ARG1, ARG2);
1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "kill", int, pid, int, signal);
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kioctl)
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kioctl ( %ld, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(Word, "ioctl", Word, fd,
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                Word, command, Word, arg, Word, ext);
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2 /* request */) {
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5800/*TXISATTY*/:
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5801/*TXTTYNAME*/:
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x412:/*no idea what any of these are*/
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x430:
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x431:
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x432:
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x441:
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x442:
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x462:
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x480:
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x482:
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x738:
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x736:
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73B:
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73C:
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73D:
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73E:
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5401:
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5403:
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0xFF01/*no_idea_at_all_what_this_is*/:
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          break;
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We don't have any specific information on it, so
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         try to do something reasonable based on direction and
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         size bits.
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         According to Simon Hausmann, _IOC_READ means the kernel
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         writes a value to the ioctl value passed from the user
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         space and the other way around with _IOC_WRITE. */
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: {
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dir  = _VKI_IOC_DIR(ARG2);
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt size = _VKI_IOC_SIZE(ARG2);
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) {
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /*
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             * Be very lax about ioctl handling; the only
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             * assumption is that the size is correct. Doesn't
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             * require the full buffer to be initialized when
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             * writing.  Without this, using some device
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             * drivers with a large number of strange ioctl
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             * commands becomes very tiresome.
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             */
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            static Int moans = 5;
1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (moans > 0 && !VG_(clo_xml)) {
1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               moans--;
1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VG_(message)(Vg_UserMsg,
1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "Warning: noted but unhandled ioctl 0x%lx"
1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            " with no size/direction hints\n",
1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            ARG2);
1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VG_(message)(Vg_UserMsg,
1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "   This could cause spurious value errors"
1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            " to appear.\n");
1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VG_(message)(Vg_UserMsg,
1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "   See README_MISSING_SYSCALL_OR_IOCTL for "
1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "guidance on writing a proper wrapper.\n" );
1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ((dir & _VKI_IOC_WRITE) && size > 0)
1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               PRE_MEM_READ( "ioctl(generic)", ARG3, size);
1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ((dir & _VKI_IOC_READ) && size > 0)
1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } /* switch */
1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_kioctl)
1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (ARG2 /*request*/) {
1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0xFF01:
1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* 100% kludge.  I have no idea what this ioctl is.  IOCINFO
1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ?  But at a guess I'd say it returns some kind of info
1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            from the kernel. */
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ARG3) POST_MEM_WRITE(ARG3, 16);
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x738: /* Shows up in MPI applications. */
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ARG3) POST_MEM_WRITE(ARG3, 4*sizeof(Word));
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x736: /* Shows up in MPI applications. */
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73B: /* Shows up in MPI applications. */
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73C: /* Shows up in MPI applications. */
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ARG3) POST_MEM_WRITE(ARG3, 16);
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* in fact only 4 needed, but being conservative */
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5401:
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* some kind of tty thing */
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (ARG3) POST_MEM_WRITE(ARG3, 32);
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	break;
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5801/*TXTTYNAME*/:
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	/* who knows if this is right.  Presumably an ascii string is
1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   written into the buffer specified by ARG3, but how long is
1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	   that buffer? */
1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (ARG3) POST_MEM_WRITE(ARG3, 16);
1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        break;
1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x412:
1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x430:
1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x431:
1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x432:
1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x441:
1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x442:
1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x462:
1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x480:
1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x482:
1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73D:
1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x73E:
1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5800/*TXISATTY*/:
1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case 0x5403:
1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We don't have any specific information on it, so
1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         try to do something reasonable based on direction and
1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         size bits.
1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         According to Simon Hausmann, _IOC_READ means the kernel
1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         writes a value to the ioctl value passed from the user
1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         space and the other way around with _IOC_WRITE. */
1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default: {
1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt dir  = _VKI_IOC_DIR(ARG2);
1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt size = _VKI_IOC_SIZE(ARG2);
1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (size > 0 && (dir & _VKI_IOC_READ)
1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             && RES == 0
1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             && ARG3 != (Addr)NULL)
1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            POST_MEM_WRITE(ARG3, size);
1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_klseek)
1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("klseek ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(long, "klseek",
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 long, fd, long, offset, long, whence, void*, arg4);
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* XXX: looks like 4th arg is a pointer to something.  Is it
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      read or written by the kernel? */
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_knlist)
1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("knlist (BOGUS HANDLER)");
1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kpread)
1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_kpread ( %ld, %#lx, %llu, %lld )",
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, (ULong)ARG3, (ULong)ARG4);
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(ssize_t, "kpread",
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, fd, char *, buf,
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 vki_size_t, count, long, offset);
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "kpread(buf)", ARG2, ARG3 );
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_kpread)
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES > 0) {
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG2, RES );
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kread)
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_read ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(ssize_t, "read",
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, fd, char *, buf, vki_size_t, count);
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   if (!ML_(fd_allowed)(ARG1, "read", tid, False))
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      SET_STATUS_Failure( VKI_EBADF );
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   else
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_kread)
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  vg_assert(SUCCESS);
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  POST_MEM_WRITE( ARG2, RES );
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kreadv)
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i;
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct vki_iovec * vec;
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* ssize_t readvx ( int fd, struct iovec*, int iovCount, int extension ) */
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kreadv ( %ld, %#lx, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(ssize_t, "kreadv",
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned long, fd, const struct iovec *, vector,
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned long, iovCount, unsigned long, extension);
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      SET_STATUS_Failure( VKI_EBADF );
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   } else {
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "kreadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG2 != 0) {
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* ToDo: don't do any of the following if the vector is invalid */
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vec = (struct vki_iovec *)ARG2;
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = 0; i < (Int)ARG3; i++)
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            PRE_MEM_WRITE( "kreadv(vector[...])",
1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           (Addr)vec[i].iov_base, vec[i].iov_len );
1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz }
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_kreadv)
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES > 0) {
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int i;
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct vki_iovec * vec = (struct vki_iovec *)ARG2;
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int remains = RES;
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* RES holds the number of bytes read. */
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < (Int)ARG3; i++) {
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Int nReadThisBuf = vec[i].iov_len;
1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (nReadThisBuf > remains) nReadThisBuf = remains;
1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         remains -= nReadThisBuf;
1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (remains < 0) VG_(core_panic)("readv: remains < 0");
1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kthread_ctl)
1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kthread_ctl (BOGUS HANDLER)");
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_ktruncate)
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("ktruncate( %#lx(%s), %lx, %lx )", ARG1,(Char*)ARG1, ARG2, ARG3 );
1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "ktruncate", char*, path, long, arg2, long, arg3 );
1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "ktruncate(path)", ARG1 );
1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kwaitpid)
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Note: args 1 and 2 (status, pid) opposite way round
1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      from generic handler */
1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kwaitpid ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "waitpid",
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int *, status, int, pid, int, options);
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 != (Addr)NULL)
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "kwaitpid(status)", ARG1, sizeof(int) );
1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_kwaitpid)
1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 != (Addr)NULL)
1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG1, sizeof(int) );
1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kwrite)
1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   Bool ok;
1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_kwrite ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(ssize_t, "kwrite",
1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 unsigned int, fd, const char *, buf, vki_size_t, count);
1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* check to see if it is allowed.  If not, try for an exemption from
1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --sim-hints=enable-outer (used for self hosting). */
1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   ok = ML_(fd_allowed)(ARG1, "write", tid, False);
1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   if (!ok && ARG1 == 2/*stderr*/
1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz           && VG_(strstr)(VG_(clo_sim_hints),"enable-outer"))
1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      ok = True;
1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   if (!ok)
1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      SET_STATUS_Failure( VKI_EBADF );
1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   else
1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_kwritev)
1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("kwritev (BOGUS HANDLER)");
1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_listen)
1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("listen (BOGUS HANDLER)");
1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_loadbind)
1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("loadbind( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "loadbind", int, flag,
1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      void*, ExportPointer, void*, ImportPointer);
1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_loadquery)
1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* loadquery ( int flags, void* buffer, unsigned int bufferlength ) */
1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("loadquery ( %#lx, %#lx, %ld )", ARG1, ARG2, ARG3);
1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "loadquery(buf)", ARG2, ARG3 );
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_loadquery)
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, ARG3 );
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_lseek)
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("lseek (%ld, %ld, %ld)", ARG1, ARG2, ARG3);
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "lseek", long, fd, long, offset, long, whence);
1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_mkdir)
1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mkdir (%#lx(%s), %#lx)", ARG1,(Char*)ARG1, ARG2);
1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "mkdir", char*, path, int, mode);
1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "mkdir(path)", ARG1 );
1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_mmap)
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mmap ( %#lx, %ld, %#lx, %#lx, %ld, %ld )",
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(void*, "mmap", void*, addr, int, len,
1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        int, prot, int, flags, int, fd, int, off);
1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_mmap)
1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  addr  = (Addr)RES;
1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord len   = (UWord)ARG2;
1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord prot  = (UWord)ARG3;
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord flags = (UWord)ARG4;
1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool r = (prot & VKI_PROT_READ) > 0;
1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool w = (prot & VKI_PROT_WRITE) > 0;
1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool x = (prot & VKI_PROT_EXEC) > 0;
1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( new_mem_mmap, addr, len, r,w,x, 0/*di_handle*/ );
1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool d = VG_(am_notify_client_mmap)( addr, len, prot, flags,
1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        0/*fake fd*/, 0/*fake offset*/);
1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (d)
1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(discard_translations)( addr, len, "POST(sys_mmap)" );
1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_mntctl)
1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mntctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3 );
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "mntctl", long, command, long, size, char*, buffer);
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "mntctl(buffer)", ARG3, ARG2 );
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_mntctl)
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES == 0) {
1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Buffer too small.  First word is the real required size. */
1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(Word) );
1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* RES is the number of struct vmount's written to the buf.  But
1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         these are variable length and to find the end would require
1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         inspecting each in turn.  So be simple and just mark the
1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         entire buffer as defined. */
1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, ARG2 );
1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_mprotect)
1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("mprotect (BOGUS HANDLER)( %#lx, %ld, %#lx )", ARG1, ARG2, ARG3);
1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "mprotect", void*, addr, long, len, long, prot);
1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_mprotect)
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool d;
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  addr = ARG1;
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord len  = ARG2;
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord prot = ARG3;
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d = VG_(am_notify_mprotect)( addr, len, prot );
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (d)
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(discard_translations)( addr, len, "POST(sys_mprotect)" );
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_munmap)
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("munmap ( %#lx, %ld )", ARG1, ARG2);
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "munmap", void*, addr, long, len);
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_munmap)
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool d;
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  addr = ARG1;
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord len  = ARG2;
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( die_mem_munmap, addr, len );
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d = VG_(am_notify_munmap)( addr, len );
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (d)
1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(discard_translations)( addr, len, "POST(sys_munmap)" );
1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_naccept)
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("naccept (%ld, %#lx, %#lx)", ARG1, ARG2, ARG3);
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "naccept", int, socket, char*, addr, int*, addrlen);
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "naccept(addrlen)", ARG3, sizeof(UInt) );
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "naccept(addr)", ARG2, *(UInt*)ARG3 );
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_naccept)
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG3, sizeof(UInt) );
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_ngetpeername)
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("ngetpeername ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "ngetpeername", int, fd, char*, name, int*, namelen);
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "ngetpeername(namelen)", ARG3, sizeof(UInt) );
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "ngetpeername(name)", ARG2, *(UInt*)ARG3 );
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_ngetpeername)
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG3, sizeof(UInt) );
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_ngetsockname)
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("ngetsockname ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "ngetsockname", int, fd, char*, name, int*, namelen);
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "ngetsockname(namelen)", ARG3, sizeof(UInt) );
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "ngetsockname(name)", ARG2, *(UInt*)ARG3 );
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_ngetsockname)
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG3, sizeof(UInt) );
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_nrecvfrom)
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("nrecvfrom ( %ld, %#lx, %ld, %ld, %#lx, %#lx )",
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ6(ssize_t, "nrecvfrom",
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, s, void*, buf, size_t, len, int, flags,
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, from, UInt*, fromlen);
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "nrecvfrom(buf)", ARG2, ARG3 );
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "nrecvfrom(fromlen)", ARG6, sizeof(UInt) );
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "nrecvfrom(from)", ARG5, *(UInt*)ARG6 );
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_nrecvfrom)
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, RES );
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG5) {
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG6, sizeof(UInt));
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG5, *(UInt*)ARG6);
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_nrecvmsg)
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("nrecvmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "nrecvmsg", long, arg1, void*, arg2, long, arg3);
1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_nsendmsg)
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("nsendmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_open) /* XXX CoG */
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   HChar  name[30];
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   SysRes sres;
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 & VKI_O_CREAT) {
1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // 3-arg version
1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("sys_open ( %#lx(%s), %#lx, %ld )",ARG1,(Char*)ARG1,ARG2,ARG3);
1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ3(long, "open",
1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const char *, filename, int, flags, int, mode);
1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // 2-arg version
1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRINT("sys_open ( %#lx(%s), %#lx )",ARG1,(Char*)ARG1,ARG2);
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_REG_READ2(long, "open",
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    const char *, filename, int, flags);
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   /* Handle the case where the open is of /proc/self/cmdline or
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      /proc/<pid>/cmdline, and just give it a copy of the fd for the
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      fake file we cooked up at startup (in m_main).  Also, seek the
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      cloned fd back to the start. */
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   if (ML_(safe_to_deref)( (void*)ARG1, 1 )
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz       && (VG_(strcmp)((Char *)ARG1, name) == 0
1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz           || VG_(strcmp)((Char *)ARG1, "/proc/self/cmdline") == 0)) {
1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      sres = VG_(dup)( VG_(cl_cmdline_fd) );
1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      SET_STATUS_from_SysRes( sres );
1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      if (!sres.isError) {
1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz         OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz         if (off < 0)
1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz            SET_STATUS_Failure( VKI_EMFILE );
1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      }
1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      return;
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   }
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Otherwise handle normally */
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_open)
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   if (!ML_(fd_allowed)(RES, "open", tid, True)) {
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      VG_(close)(RES);
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      SET_STATUS_Failure( VKI_EMFILE );
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   } else {
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz      if (VG_(clo_track_fds))
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz         ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   //zz   }
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_pipe)
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_pipe ( %#lx )", ARG1);
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "pipe", int *, filedes);
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_pipe)
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz   Int *p = (Int *)ARG1;
1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz  if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz      !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz    VG_(close)(p[0]);
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz    VG_(close)(p[1]);
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz    SET_STATUS_Failure( VKI_EMFILE );
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  //zz  } else {
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    POST_MEM_WRITE( ARG1, 2*sizeof(int) );
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    //zz    if (VG_(clo_track_fds)) {
1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    //zz      ML_(record_fd_open_nameless)(tid, p[0]);
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    //zz      ML_(record_fd_open_nameless)(tid, p[1]);
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    //zz    }
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    //zz  }
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_privcheck)
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("privcheck ( %ld )", ARG1);
1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "privcheck", int, arg1);
1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_readlink)
1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("readlink ( 0x%lx(%s),0x%lx,%ld )", ARG1,(Char*)ARG1, ARG2, ARG3);
1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "readlink",
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 const char *, path, char *, buf, int, bufsiz);
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_readlink)
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, RES + 1 );
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_recv)
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("recv ( %ld, %#lx, %ld, %ld )",
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4);
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(int, "recv", int, fd, void*, buf, int, len, int, flags);
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "recv(buf)", ARG2, ARG3);
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_recv)
1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES > 0)
1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE(ARG2, RES);
1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_rename)
1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT( "rename ( %#lx(%s), %#lx(%s) )", ARG1,(Char*)ARG1, ARG2,(Char*)ARG2 );
1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "rename", char*, frompath, char*, topath);
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "rename(frompath)", ARG1 );
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "rename(topath)", ARG2 );
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sbrk)
1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sbrk (BOGUS HANDLER)( %#lx )", ARG1);
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "sbrk", long, arg1);
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* After a zero sbrk, disallow aspacem from doing sbrk, since libc
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      might rely on the value returned by this syscall. */
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* 1 Oct 06: not currently used (aspacemgr-aix5.c ignores it) */
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(am_aix5_sbrk_allowed) = toBool(ARG1 != 0);
1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Disallow libc from moving the brk backwards as that might trash
1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SkPreAlloc sections acquired by aspacem from previous uses of
1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sbrk. */
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 < 0)
1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ARG1 = 0;
1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Do this as a sync syscall, so the sbrk_allowed flag gets turned
1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      back on ASAP.  Typically libc does sbrk(0) and then sbrk(x > 0)
1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in quick succession.  Although surely it should hold some kind
2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of lock at that point, else it cannot safely use the result from
2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the first sbrk call to influence the second one? */
2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags &= ~SfMayBlock;
2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_sbrk)
2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   handle_sbrk(ARG1);
2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sched_get_priority_max)
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sched_get_priority_max ( %ld )", ARG1);
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sched_get_priority_max", int, arg1);
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sem_destroy)
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_destroy ( %#lx )", ARG1);
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_destroy", sem_t*, sem);
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "sem_destroy(sem)", ARG1, sizeof(sem_t) );
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sem_init)
2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_init ( %#lx, %ld, %ld )", ARG1, ARG2, ARG3);
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "sem_init", sem_t*, sem, int, pshared, int, value);
2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "sem_init(sem)", ARG1, sizeof(sem_t) );
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_sem_init)
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG1, sizeof(sem_t) );
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sem_post)
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sem_post ( %#lx )", ARG1);
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "sem_post", sem_t*, sem);
2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ("sem_post(sem)", ARG1, sizeof(sem_t));
2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_sem_post)
2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, sizeof(sem_t));
2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_send)
2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("send (BOGUS HANDLER)( %ld, %#lx, %ld, %ld )",
2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4);
2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_setgid)
2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setgid ( %ld )", ARG1);
2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "setgid", int, uid);
2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_setsockopt)
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setsockopt ( %ld, %ld, %ld, %#lx, %ld )",
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1,ARG2,ARG3,ARG4,ARG5 );
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ5(long, "setsockopt",
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 long, socket, long, level, long, optionname,
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 void*, optionvalue, long, optlen);
2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG4)
2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "setsockopt(optionvalue)", ARG4, ARG5 );
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_setuid)
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("setuid ( %ld )", ARG1);
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "setuid", int, uid);
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UWord get_shm_size ( Word shmid )
2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SysRes res;
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct shmid_ds buf;
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(__NR_AIX5_shmctl != __NR_AIX5_UNKNOWN);
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   res = VG_(do_syscall3)(__NR_AIX5_shmctl, shmid, IPC_STAT, (UWord)&buf);
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0)
2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("XXX: shm_size(%ld) = %ld %ld\n", shmid, res.res, res.err);
2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (res.isError) {
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0)
2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("XXX: shm_size(shmid = %ld): FAILED\n", shmid);
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return 0* 4096;
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return buf.shm_segsz;
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* fails with 22 and 13 (22 = EINVAL, Invalid argument,
2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      13 = EACCES, Permission denied) */
2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* shmat (4, 0x0, 0x1800) --> Success(0x40000000)
2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX: shm_size(4) = -1 22
2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shmat: seg size = 0
2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX: shm_size(4) = -1 22
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shmat (5, 0x0, 0x1800) --> Success(0x50000000)
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX: shm_size(5) = -1 13
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shmat: seg size = 0
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX: shm_size(5) = -1 13
2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shmat (4, 0x0, 0x1800) --> Success(0x40000000)
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX: shm_size(4) = -1 22
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shmat: seg size = 0
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XXX: shm_size(4) = -1 22
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_shmat)
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord segmentSize;
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* void* shmat ( int shmid, const void* shmaddr, int flags ) */
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmat (%ld, %#lx, %#lx)", ARG1, ARG2, ARG3);
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(void*, "shmat", int, shmid, void*, shmaddr, int, flags);
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   segmentSize = get_shm_size( ARG1 );
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("shmat: seg size = %lu\n", segmentSize);
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_shmat)
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt segmentSize;
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(RES != -1L);
2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   segmentSize = get_shm_size ( ARG1 );
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ( segmentSize > 0 ) {
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool d;
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ARG2 & SHM_RDONLY)
2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         prot &= ~VKI_PROT_WRITE;
2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d = VG_(am_notify_client_shmat)( RES, VG_PGROUNDUP(segmentSize), prot );
2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* we don't distinguish whether it's read-only or
2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       * read-write -- it doesn't matter really. */
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_TRACK( new_mem_mmap, RES, segmentSize, True, True, False, 0/*di_handle*/ );
2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d)
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(discard_translations)( (Addr64)RES,
2137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (ULong)VG_PGROUNDUP(segmentSize),
2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    "ML_(generic_POST_sys_shmat)" );
2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_shmctl)
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3 );
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "shmctl", int, shmid, int, command, void*, buffer);
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3)
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "shmctl(buffer)", ARG3, sizeof(struct shmid_ds) );
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_shmctl)
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ((ARG3) && ARG2 == IPC_STAT)
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct shmid_ds) );
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_shmdt)
2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmdt ( %#lx )", ARG1);
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "shmdt", void*, address);
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_shmdt)
2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   NSegment const*const s = VG_(am_find_nsegment)(ARG1);
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (s != NULL) {
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  s_start = s->start;
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SizeT s_len   = s->end+1 - s->start;
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool  d;
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(s->kind == SkShmC && s->start == ARG1);
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d = VG_(am_notify_munmap)(s_start, s_len);
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* s is now invalid; do not use after here */
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_TRACK( die_mem_munmap, s_start, s_len );
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (d)
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(discard_translations)( (Addr64)s_start,
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (ULong)s_len,
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    "ML_(generic_POST_sys_shmdt)" );
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_shmget)
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shmget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3 );
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "shmget", key_t, key, size_t, size, int, shmFlag);
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_shutdown)
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("shutdown (BOGUS HANDLER)");
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sigcleanup)
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sigcleanup (UNDOCUMENTED)");
2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sigprocmask)
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sigprocmask ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "sigprocmask",
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset);
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2 != 0)
2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG3 != 0)
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_from_SysRes(
2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(do_sys_sigprocmask) ( tid, ARG1, (vki_sigset_t*)ARG2,
2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                           (vki_sigset_t*)ARG3 )
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (SUCCESS)
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     *flags |= SfPollAfter;
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_sigprocmask)
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (RES == 0 && ARG3 != 0)
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_socket)
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("socket ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol);
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_statfs)
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_statfs ( %#lx(%s), %#lx )",ARG1,(Char*)ARG1,ARG2);
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct statfs) );
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_statfs)
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_statx)
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("statx ( %#lx(%s), %#lx, %ld, %ld )", ARG1,(Char*)ARG1,ARG2,ARG3,ARG4);
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "statx(file_name)", ARG1 );
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ4(Word, "statx", UWord, fd, void*, buf,
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                UWord, len, UWord, cmd);
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "statx(buf)", ARG2, ARG3 );
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_statx)
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, ARG3 );
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_symlink)
2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("symlink (BOGUS HANDLER)");
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sys_parm)
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sys_parm (%ld, %ld, %#lx)", ARG1, ARG2, ARG3);
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "sys_parm", int, cmd, int, cmdflag,
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      struct vario*, parmp);
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* this is a bit of a kludge, but if parmp has uninitialised areas
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      and we're doing SYSP_SET, lots of errors will be tiresomely
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      reported.  Hence just ignore the definedness of the area and
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      only check addressability. */
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "sys_parm(parmp)", ARG3, sizeof(struct vario));
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_sys_parm)
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1 == SYSP_GET)
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG3, sizeof(struct vario) );
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_sysconfig)
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("sysconfig ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "sysconfig", int, cmd, void*, parmp, int, parmlen);
2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* It may be that the area is read sometimes as well as written,
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      but for the same reasons as sys_parm, just check addressibility,
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      not definedness. */
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "sysconfig(parmp)", ARG2, ARG3 );
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_sysconfig)
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG2, ARG3 );
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_create)
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_create ( )");
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_thread_create)
2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("new lwpid is %ld\n", RES);
2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Allocate a new thread slot (which sets it to VgTs_Init), and
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      record the lwpid in it, so can later find it again when handling
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sys_thread_setstate for that lwpid. */
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadId     ctid = VG_(alloc_ThreadState)();
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* ctst = VG_(get_ThreadState)(ctid);
2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(ctst->status == VgTs_Init);
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { /* Clear all os_state fields except for the vg stack ones, so any
2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        existing stack gets reused. */
2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Addr v_s_b    = ctst->os_state.valgrind_stack_base;
2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     Addr v_s_i_SP = ctst->os_state.valgrind_stack_init_SP;
2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(memset)(&ctst->os_state, 0, sizeof(ThreadOSstate));
2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     ctst->os_state.valgrind_stack_base    = v_s_b;
2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     ctst->os_state.valgrind_stack_init_SP = v_s_i_SP;
2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ctst->os_state.lwpid = RES;
2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_init)
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "thread_init", long, arg1, long, arg2);
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_init (BOGUS HANDLER) ( %#lx, %#lx )", ARG1, ARG2);
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_kill)
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int target_lwpid, my_lwpid;
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_kill ( %ld, %ld )", ARG1, ARG2);
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ( ((Word)ARG1) == (Word)(-1)
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        && ARG2 == VKI_SIGSEGV ) {
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* too difficult to continue; give up. */
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(aix5_set_threadstate_for_emergency_exit)
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (tid, "exiting due to thread_kill(..,SIGSEGV) to process");
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Success(0);
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Check to see if this kill gave us a pending signal */
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfPollAfter;
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   target_lwpid = (Int)ARG1;
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   my_lwpid     = VG_(gettid)();
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* we still hold the lock.  Do deadlock-avoidance stuff. */
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (target_lwpid == my_lwpid) {
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* sending a signal to myself, which may be fatal.  Therefore
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         drop the lock so that if the signal kills me, some other
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         thread can pick it up. */
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags |= SfMayBlock;
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* sending a signal to some other thread, which may kill it;
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         therefore I'd better hold on to the lock to ensure that the
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         target doesn't get killed whilst holding it. */
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* thread_setmymask_fast is handled on a per platform basis */
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_setmystate)
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* args: struct tstate *, struct tstate *
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      I assume: first is new state, if not NULL.
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Second is place to write the previous state, if not NULL.
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (in the style of sigaction) */
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_setmystate (BOGUS HANDLER) ( %#lx, %#lx )",
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2 );
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(long, "thread_setmystate",
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct tstate *, newstate,
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       struct tstate *, oldstate );
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG1)
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_READ( "thread_setmystate(arg1)", ARG1, sizeof(struct tstate) );
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2)
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRE_MEM_WRITE( "thread_setmystate(arg2)", ARG2, sizeof(struct tstate) );
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (1 && VG_(clo_trace_syscalls) && ARG1)
2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(aix5debugstuff_show_tstate)(ARG1, "thread_setmystate (NEW)");
2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct tstate* newts  = (struct tstate*)ARG1;
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct tstate* oldts  = (struct tstate*)ARG2;
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Are we just messing with the signal mask?  If so intercept it
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      and do it ourselves.  Same idea as handling for
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      thread_setmymask_fast in 32-bit mode. */
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (newts && newts->flags == TSTATE_CHANGE_SIGMASK) {
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_sigset_t* newset = newts ? (vki_sigset_t*)&newts->sigmask : NULL;
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vki_sigset_t* oldset = oldts ? (vki_sigset_t*)&oldts->sigmask : NULL;
2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_from_SysRes(
2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(do_sys_sigprocmask) ( tid, VKI_SIG_SETMASK, newset, oldset )
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *flags &= ~SfMayBlock;
2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_thread_setmystate)
2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ARG2)
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      POST_MEM_WRITE( ARG2, sizeof(struct tstate) );
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0 && VG_(clo_trace_syscalls) && ARG2)
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(aix5debugstuff_show_tstate)(ARG2, "thread_setmystate (OLD)");
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_setmystate_fast)
2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord how = ARG1;
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* args: ?? */
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_setmystate_fast (BOGUS HANDLER)"
2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         "(%#lx,%#lx(%s),%#lx(%s))",
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1,
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG2, ML_(aix5debugstuff_pc_to_fnname)(ARG2),
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG3, ML_(aix5debugstuff_pc_to_fnname)(ARG3)
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(long, "thread_setmystate_fast",
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       long, arg1, long, arg2, long, arg3);
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (1 && VG_(clo_trace_syscalls))
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(aix5debugstuff_show_tstate_flags)( how );
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (how & TSTATE_CHANGE_FLAGS) {
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Messing with cancellation type/state.  Pay attention. */
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool async    = (how & TSTATE_CANCEL_DEFER) == 0;
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool disabled = (how & TSTATE_CANCEL_DISABLE) > 0;
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ThreadState* tst = VG_(get_ThreadState)(tid);
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(clo_trace_syscalls))
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("(cancellation state -> %s %s)",
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     async ? "ASYNC" : "DEFER",
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     disabled ? "DISABLED" : " ENABLED");
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->os_state.cancel_async    = async;
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tst->os_state.cancel_disabled = disabled;
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If cancellation has been enabled for this thread and there is
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         a request outstanding, honour it now. */
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((!disabled)
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          && tst->os_state.cancel_progress == Canc_Requested) {
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (VG_(clo_trace_syscalls))
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("(honouring previous cancellation request)");
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tst->os_state.cancel_progress = Canc_Actioned;
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Bool ok = ML_(aix5_force_thread_into_pthread_exit)(tid);
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (!ok) {
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* now at serious risk of deadlock/livelock.  Give up
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               rather than continue. */
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(aix5_set_threadstate_for_emergency_exit)
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               (tid, "pthread_cancel(case1): "
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "cannot find pthread_exit; aborting");
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            SET_STATUS_Success(0);
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return;
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      SET_STATUS_Success(0);
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* In all other cases, hand to kernel. */
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* thread_setstate is handled in syswrap-ppc{32,64}-aix5.c. */
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_terminate_unlock)
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ThreadState* tst;
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* simple; just make this thread exit */
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_terminate_unlock( %#lx )", ARG1);
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(void, "thread_terminate_unlock", void*, exitcode);
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst = VG_(get_ThreadState)(tid);
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Drop the lock we were holding, since we're not really going to
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      exit the host thread with thread_terminate_unlock. */
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("XXXXX dropping lock\n");
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (1) VG_(do_syscall1)(__NR_AIX5_thread_unlock, ARG1);
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Set the thread's status to be exiting, then claim that the
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      syscall succeeded. */
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->exitreason = VgSrc_ExitThread;
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tst->os_state.exitcode = 0;
2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SET_STATUS_Success(0);
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_tsleep)
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_tsleep (BOGUS HANDLER)( %ld, %#lx, %#lx, %#lx )",
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4 );
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_tsleep_event)
2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_tsleep_event (UNDOCUMENTED)( %#lx, %#lx, %ld, %#lx )",
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3, ARG4 );
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_twakeup)
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_twakeup (BOGUS HANDLER)( tid=%ld, val=%#lx )", ARG1, ARG2 );
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_twakeup_event)
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_twakeup_event (BOGUS HANDLER)( %#lx, %ld, %ld )",
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ARG1, ARG2, ARG3 );
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_unlock)
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_unlock (BOGUS HANDLER)" );
2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_waitlock)
2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_waitlock (BOGUS HANDLER)" );
2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_thread_waitlock_)
2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("thread_waitlock_ (BOGUS HANDLER)" );
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_times)
2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("times ( %#lx )", ARG1);
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(long, "times", struct tms *, buffer);
2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("times(buf)", ARG1, sizeof(struct tms) );
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_times)
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG1, sizeof(struct tms) );
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_umask)
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("umask (BOGUS HANDLER)");
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_uname)
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("uname ( %#lx )", ARG1);
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE( "uname(Name)", ARG1, sizeof(struct utsname));
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_uname)
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE( ARG1, sizeof(struct utsname));
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_unlink)
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("unlink ( %#lx(%s) )", ARG1, (Char*)ARG1 );
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ1(int, "unlink", char*, path);
2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "unlink(path)", ARG1 );
2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_utimes)
2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("utimes ( %#lx(%s), %#lx )", ARG1,(Char*)ARG1, ARG2);
2557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ2(int, "utimes", char*, path, struct timeval*, times);
2558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_RASCIIZ( "utimes(path)", ARG1 );
2559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_READ( "utimes(times)", ARG2, 2 * sizeof(struct vki_timeval) );
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_vmgetinfo)
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("vmgetinfo ( %#lx, %ld, %ld )", ARG1, ARG2, ARG3 );
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_REG_READ3(int, "vmgetinfo", void*, out, int, command, int, arg);
2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* It looks like libc's vmgetinfo just hands stuff through to the
2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      syscall.  The man page says that the interpretation of ARG3(arg)
2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      depends on ARG2(cmd); nevertheless in all cases basically this
2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      writes the buffer (ARG1, ARG3). */
2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRE_MEM_WRITE("vmgetinfo(buf)", ARG1, ARG3);
2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPOST(sys_vmgetinfo)
2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(SUCCESS);
2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POST_MEM_WRITE(ARG1, ARG3);
2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPRE(sys_yield)
2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *flags |= SfMayBlock;
2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRINT("yield ( )");
2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef PRE
2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#undef POST
2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGO_aix5)
2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
2592