Home | History | Annotate | Download | only in m_syswrap
      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 (at) 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. */
     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 
    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. */
    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. */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 }
    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 
    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 
    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 
    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 
    506 PRE(sys__fp_fpscrx_sc)
    507 {
    508    PRINT("_fp_fpscrx_sc (BOGUS HANDLER)");
    509 }
    510 
    511 PRE(sys__getpgrp)
    512 {
    513    PRINT("_getpgrp (BOGUS HANDLER)");
    514 }
    515 
    516 PRE(sys__getpid)
    517 {
    518    PRINT("_getpid ( )");
    519 }
    520 
    521 PRE(sys__getppid)
    522 {
    523    PRINT("_getppid ( )");
    524 }
    525 
    526 PRE(sys__getpriority)
    527 {
    528    PRINT("_getpriority (BOGUS HANDLER)");
    529 }
    530 
    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 }
    546 POST(sys__nsleep)
    547 {
    548    if (ARG2)
    549       POST_MEM_WRITE(ARG2, sizeof(struct timestruc_t));
    550 }
    551 
    552 PRE(sys__pause)
    553 {
    554   *flags |= SfMayBlock;
    555   PRINT("_pause ( )");
    556   PRE_REG_READ0(long, "pause");
    557 }
    558 
    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 }
    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 
    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 
    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 
    629 PRE(sys__setpgid)
    630 {
    631    PRINT("setpgid ( %ld, %ld )", ARG1, ARG2);
    632    PRE_REG_READ2(int, "setpgid", int, pid, int, pgid);
    633 }
    634 
    635 PRE(sys__setsid)
    636 {
    637    PRINT("setsid ( )");
    638 }
    639 
    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 }
    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 
    671 PRE(sys__thread_self)
    672 {
    673    PRINT("_thread_self ( )");
    674 }
    675 
    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 
    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 
    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 
    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 }
    703 POST(sys_appgetrlimit)
    704 {
    705    POST_MEM_WRITE( ARG2, sizeof(struct rlimit) );
    706 }
    707 
    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 }
    715 POST(sys_appgetrusage)
    716 {
    717    POST_MEM_WRITE( ARG2, sizeof(struct rusage) );
    718 }
    719 
    720 PRE(sys_apprestimer)
    721 {
    722    PRINT("apprestimer (BOGUS HANDLER)");
    723 }
    724 
    725 PRE(sys_appsetrlimit)
    726 {
    727    PRINT("appsetrlimit (BOGUS HANDLER)");
    728 }
    729 
    730 PRE(sys_appulimit)
    731 {
    732    PRINT("appulimit ( %ld, %ld )", ARG1, ARG2);
    733    PRE_REG_READ2(long, "appulimit", long, arg1, long, arg2);
    734 }
    735 
    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 
    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 
    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 
    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 
    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 
    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.
    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 }
    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 }
    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 
   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 }
   1073 POST(sys_finfo)
   1074 {
   1075    POST_MEM_WRITE( ARG3, ARG4 );
   1076 }
   1077 
   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 }
   1084 POST(sys_fstatfs)
   1085 {
   1086    POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
   1087 }
   1088 
   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 }
   1096 POST(sys_fstatx)
   1097 {
   1098    POST_MEM_WRITE( ARG2, ARG3 );
   1099 }
   1100 
   1101 PRE(sys_fsync)
   1102 {
   1103    PRINT("fsync ( %ld )", ARG1);
   1104    PRE_REG_READ1(int, "fsync", int, fd);
   1105 }
   1106 
   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 }
   1116 POST(sys_getdirent)
   1117 {
   1118    vg_assert(SUCCESS);
   1119    POST_MEM_WRITE( ARG2, RES );
   1120 }
   1121 
   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 }
   1132 POST(sys_getdirent64)
   1133 {
   1134    vg_assert(SUCCESS);
   1135    POST_MEM_WRITE( ARG2, RES );
   1136 }
   1137 
   1138 PRE(sys_getdomainname)
   1139 {
   1140    PRINT("getdomainname ( %#lx, %ld )", ARG1, ARG2 );
   1141    PRE_MEM_WRITE( "getdomainname(buf)", ARG1, ARG2 );
   1142 }
   1143 POST(sys_getdomainname)
   1144 {
   1145    POST_MEM_WRITE( ARG1, ARG2 );
   1146 }
   1147 
   1148 PRE(sys_getgidx)
   1149 {
   1150    PRINT("getgidx ( %ld )", ARG1);
   1151    PRE_REG_READ1(UInt, "getgidx", long, arg1);
   1152 }
   1153 
   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 }
   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 
   1168 PRE(sys_gethostname)
   1169 {
   1170    PRINT("gethostname ( %#lx, %ld )", ARG1, ARG2);
   1171    PRE_MEM_WRITE( "gethostname(buf)", ARG1, ARG2 );
   1172 }
   1173 POST(sys_gethostname)
   1174 {
   1175    POST_MEM_WRITE( ARG1, ARG2 );
   1176 }
   1177 
   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 }
   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. */
   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 }
   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 
   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 
   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 }
   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 
   1245 PRE(sys_gettimerid)
   1246 {
   1247    PRINT("gettimerid ( %ld, %ld )", ARG1, ARG2);
   1248    PRE_REG_READ2(int, "gettimerid", int, timertype, int, notifytype);
   1249 }
   1250 
   1251 PRE(sys_getuidx)
   1252 {
   1253    PRINT("getuidx ( %ld )", ARG1);
   1254    PRE_REG_READ1(UInt, "getuidx", UInt, arg1);
   1255 }
   1256 
   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 }
   1270 POST(sys_incinterval)
   1271 {
   1272    if (ARG3)
   1273       POST_MEM_WRITE( ARG3, sizeof(struct itimerstruc_t));
   1274 }
   1275 
   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 }
   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;
   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 
   1375 PRE(sys_kftruncate)
   1376 {
   1377    PRINT("kftruncate (BOGUS HANDLER)");
   1378 }
   1379 
   1380 PRE(sys_kgetsidx)
   1381 {
   1382    PRINT("kgetsidx ( %ld )", ARG1);
   1383    PRE_REG_READ1(Word, "kgetsidx", Word, arg1);
   1384 }
   1385 
   1386 PRE(sys_kill)
   1387 {
   1388    PRINT("kill ( %ld, %ld )", ARG1, ARG2);
   1389    PRE_REG_READ2(int, "kill", int, pid, int, signal);
   1390 }
   1391 
   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 }
   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 
   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 
   1538 PRE(sys_knlist)
   1539 {
   1540    PRINT("knlist (BOGUS HANDLER)");
   1541 }
   1542 
   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 }
   1553 POST(sys_kpread)
   1554 {
   1555    vg_assert(SUCCESS);
   1556    if (RES > 0) {
   1557       POST_MEM_WRITE( ARG2, RES );
   1558    }
   1559 }
   1560 
   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 }
   1572 POST(sys_kread)
   1573 {
   1574   vg_assert(SUCCESS);
   1575   POST_MEM_WRITE( ARG2, RES );
   1576 }
   1577 
   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 }
   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 
   1620 PRE(sys_kthread_ctl)
   1621 {
   1622    *flags |= SfMayBlock;
   1623    PRINT("kthread_ctl (BOGUS HANDLER)");
   1624 }
   1625 
   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 
   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 }
   1645 POST(sys_kwaitpid)
   1646 {
   1647    if (ARG1 != (Addr)NULL)
   1648       POST_MEM_WRITE( ARG1, sizeof(int) );
   1649 }
   1650 
   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 
   1670 PRE(sys_kwritev)
   1671 {
   1672    PRINT("kwritev (BOGUS HANDLER)");
   1673 }
   1674 
   1675 PRE(sys_listen)
   1676 {
   1677    PRINT("listen (BOGUS HANDLER)");
   1678 }
   1679 
   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 
   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 }
   1693 POST(sys_loadquery)
   1694 {
   1695    vg_assert(SUCCESS);
   1696    POST_MEM_WRITE( ARG2, ARG3 );
   1697 }
   1698 
   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 
   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 
   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 }
   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 
   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 }
   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 
   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 }
   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 
   1774 PRE(sys_munmap)
   1775 {
   1776    PRINT("munmap ( %#lx, %ld )", ARG1, ARG2);
   1777    PRE_REG_READ2(int, "munmap", void*, addr, long, len);
   1778 }
   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 
   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 }
   1798 POST(sys_naccept)
   1799 {
   1800    POST_MEM_WRITE( ARG3, sizeof(UInt) );
   1801    POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
   1802 }
   1803 
   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 }
   1811 POST(sys_ngetpeername)
   1812 {
   1813    POST_MEM_WRITE( ARG3, sizeof(UInt) );
   1814    POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
   1815 }
   1816 
   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 }
   1824 POST(sys_ngetsockname)
   1825 {
   1826    POST_MEM_WRITE( ARG3, sizeof(UInt) );
   1827    POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
   1828 }
   1829 
   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 }
   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 
   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 
   1860 PRE(sys_nsendmsg)
   1861 {
   1862    *flags |= SfMayBlock;
   1863    PRINT("nsendmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
   1864 }
   1865 
   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 }
   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 
   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 }
   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 
   1942 PRE(sys_privcheck)
   1943 {
   1944    PRINT("privcheck ( %ld )", ARG1);
   1945    PRE_REG_READ1(int, "privcheck", int, arg1);
   1946 }
   1947 
   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 }
   1956 POST(sys_readlink)
   1957 {
   1958    POST_MEM_WRITE( ARG2, RES + 1 );
   1959 }
   1960 
   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 }
   1969 POST(sys_recv)
   1970 {
   1971    if (RES > 0)
   1972       POST_MEM_WRITE(ARG2, RES);
   1973 }
   1974 
   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 
   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 }
   2004 POST(sys_sbrk)
   2005 {
   2006    vg_assert(SUCCESS);
   2007    handle_sbrk(ARG1);
   2008 }
   2009 
   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 
   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 
   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 }
   2029 POST(sys_sem_init)
   2030 {
   2031    POST_MEM_WRITE( ARG1, sizeof(sem_t) );
   2032 }
   2033 
   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 }
   2040 POST(sys_sem_post)
   2041 {
   2042    POST_MEM_WRITE(ARG1, sizeof(sem_t));
   2043 }
   2044 
   2045 PRE(sys_send)
   2046 {
   2047    *flags |= SfMayBlock;
   2048    PRINT("send (BOGUS HANDLER)( %ld, %#lx, %ld, %ld )",
   2049          ARG1, ARG2, ARG3, ARG4);
   2050 }
   2051 
   2052 PRE(sys_setgid)
   2053 {
   2054    PRINT("setgid ( %ld )", ARG1);
   2055    PRE_REG_READ1(void, "setgid", int, uid);
   2056 }
   2057 
   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 
   2069 PRE(sys_setuid)
   2070 {
   2071    PRINT("setuid ( %ld )", ARG1);
   2072    PRE_REG_READ1(void, "setuid", int, uid);
   2073 }
   2074 
   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 }
   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 }
   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 
   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 }
   2149 POST(sys_shmctl)
   2150 {
   2151    if ((ARG3) && ARG2 == IPC_STAT)
   2152       POST_MEM_WRITE( ARG3, sizeof(struct shmid_ds) );
   2153 }
   2154 
   2155 PRE(sys_shmdt)
   2156 {
   2157    PRINT("shmdt ( %#lx )", ARG1);
   2158    PRE_REG_READ1(long, "shmdt", void*, address);
   2159 }
   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 
   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 
   2187 PRE(sys_shutdown)
   2188 {
   2189    PRINT("shutdown (BOGUS HANDLER)");
   2190 }
   2191 
   2192 PRE(sys_sigcleanup)
   2193 {
   2194    PRINT("sigcleanup (UNDOCUMENTED)");
   2195 }
   2196 
   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 }
   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 
   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 
   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 }
   2235 POST(sys_statfs)
   2236 {
   2237    POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
   2238 }
   2239 
   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 }
   2248 POST(sys_statx)
   2249 {
   2250    POST_MEM_WRITE( ARG2, ARG3 );
   2251 }
   2252 
   2253 PRE(sys_symlink)
   2254 {
   2255    PRINT("symlink (BOGUS HANDLER)");
   2256 }
   2257 
   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 }
   2269 POST(sys_sys_parm)
   2270 {
   2271    if (ARG1 == SYSP_GET)
   2272       POST_MEM_WRITE( ARG3, sizeof(struct vario) );
   2273 }
   2274 
   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 }
   2284 POST(sys_sysconfig)
   2285 {
   2286    POST_MEM_WRITE( ARG2, ARG3 );
   2287 }
   2288 
   2289 PRE(sys_thread_create)
   2290 {
   2291    *flags |= SfMayBlock;
   2292    PRINT("thread_create ( )");
   2293 }
   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 
   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 
   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 
   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 }
   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 
   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 
   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 
   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 
   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 
   2489 PRE(sys_thread_twakeup)
   2490 {
   2491    *flags |= SfMayBlock;
   2492    PRINT("thread_twakeup (BOGUS HANDLER)( tid=%ld, val=%#lx )", ARG1, ARG2 );
   2493 }
   2494 
   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 
   2502 PRE(sys_thread_unlock)
   2503 {
   2504    *flags |= SfMayBlock;
   2505    PRINT("thread_unlock (BOGUS HANDLER)" );
   2506 }
   2507 
   2508 PRE(sys_thread_waitlock)
   2509 {
   2510    *flags |= SfMayBlock;
   2511    PRINT("thread_waitlock (BOGUS HANDLER)" );
   2512 }
   2513 
   2514 PRE(sys_thread_waitlock_)
   2515 {
   2516    *flags |= SfMayBlock;
   2517    PRINT("thread_waitlock_ (BOGUS HANDLER)" );
   2518 }
   2519 
   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 }
   2526 POST(sys_times)
   2527 {
   2528    POST_MEM_WRITE( ARG1, sizeof(struct tms) );
   2529 }
   2530 
   2531 PRE(sys_umask)
   2532 {
   2533    PRINT("umask (BOGUS HANDLER)");
   2534 }
   2535 
   2536 PRE(sys_uname)
   2537 {
   2538    PRINT("uname ( %#lx )", ARG1);
   2539    PRE_MEM_WRITE( "uname(Name)", ARG1, sizeof(struct utsname));
   2540 }
   2541 POST(sys_uname)
   2542 {
   2543    vg_assert(SUCCESS);
   2544    POST_MEM_WRITE( ARG1, sizeof(struct utsname));
   2545 }
   2546 
   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 
   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 
   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 }
   2572 POST(sys_vmgetinfo)
   2573 {
   2574    vg_assert(SUCCESS);
   2575    POST_MEM_WRITE(ARG1, ARG3);
   2576 }
   2577 
   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