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