A major overhaul of all machinery to do with syscalls, but mostly of
the m_syscalls module.  Fundamentally the aim of the overhaul is to
clean up the logic and abstractions surrounding syscalls in order that
we can cleanly support ppc32 and other new targets.  Aims in detail:

* To further decouple the syscall PRE/POST wrappers from specifics of
  how those values are stored on a given platform.  The wrappers look
  the same as they did before, mostly (eg, references to ARGn and
  RES are unchanged), but now those macros refer to values in structs
  SyscallArgs and SyscallStatus (see priv_types_n_macros.h).

* Complete overhaul of the driver logic for syscalls.  The resulting
  logic is algorithmically identical to what we had before, but is
  more documented, and deals with moving arg/result data between
  platform specific representations and the canonical forms in
  structs SyscallArgs and SyscallStatus.

* Also as a result of this change, remove problems in the old logic
  due to assignments of RES in PRE wrappers trashing the ARGs whilst
  we still need to see them.

* Lots of other cleanups and documentation.  There is extensive
  commentary in syscalls-main.c.

The driver logic has been placed in its own file, syscalls-main.c.

New/deleted files in m_syscalls:

* syscalls.c is divided up into syscalls-main.c, containing driver
  logic, and syscalls-generic.c, containing generic Unix wrappers.

* priv_syscalls.h is chopped up into priv_types_n_macros.h
  and priv_syscalls-{generic,main}.h.

                           ------------

All the above changes are in m_syscalls.  However there is one
system-wide change as a result of all this.

The x86-linux assumption that syscall return values in the range -4095
.. -1 are errors and all others are values, has been done away with
everywhere.  Instead there is a new basic type SysRes which holds a
system call result in a platform-neutral way.

Everywhere that previously an Int would have held a system call
result, there is now a SysRes in its place.

                           ------------

Almost everything works on SuSE 9.1 (LinuxThreads) again.  NPTL will
still be majorly broken; I will commit fixes shortly.  AMD64 is also
totalled.  I will get to that too.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3849 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/core.h b/coregrind/core.h
index a371342..6b66820 100644
--- a/coregrind/core.h
+++ b/coregrind/core.h
@@ -105,7 +105,7 @@
 /* system/mman.h */
 extern void* VG_(mmap)       ( void* start, SizeT length, UInt prot, UInt flags,
                                UInt sf_flags, UInt fd, OffT offset );
-extern void* VG_(mmap_native)( void* start, SizeT length, UInt prot, UInt flags,
+extern SysRes VG_(mmap_native)( void* start, SizeT length, UInt prot, UInt flags,
                                               UInt fd, OffT offset );
 extern Int VG_(munmap)       ( void* start, SizeT length );
 extern Int VG_(mprotect)       ( void *start, SizeT length, UInt prot );
@@ -120,6 +120,16 @@
 
 extern void   VG_(nanosleep)(struct vki_timespec *);
 
+/* Simple Valgrind-internal atfork mechanism */
+/* Internal atfork handlers */
+typedef void (*vg_atfork_t)(ThreadId);
+extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, 
+                                         vg_atfork_t child);
+extern void VG_(do_atfork_pre)   (ThreadId tid);
+extern void VG_(do_atfork_parent)(ThreadId tid);
+extern void VG_(do_atfork_child) (ThreadId tid);
+
+
 /* ---------------------------------------------------------------------
    Exports of vg_syscall.S
    ------------------------------------------------------------------ */
@@ -129,16 +139,6 @@
 // cause problems when passing 32-bit integers on 64-bit platforms, because
 // the top 32-bits might not be zeroed appropriately, eg. as would happen
 // with the 6th arg on AMD64 which is passed on the stack.
-extern Word VG_(do_syscall) ( UInt, UWord, UWord, UWord, UWord, UWord, UWord );
-
-// Macros make life easier.
-#define vgPlain_do_syscall0(s)             VG_(do_syscall)((s),0,0,0,0,0,0)
-#define vgPlain_do_syscall1(s,a)           VG_(do_syscall)((s),(a),0,0,0,0,0)
-#define vgPlain_do_syscall2(s,a,b)         VG_(do_syscall)((s),(a),(b),0,0,0,0)
-#define vgPlain_do_syscall3(s,a,b,c)       VG_(do_syscall)((s),(a),(b),(c),0,0,0)
-#define vgPlain_do_syscall4(s,a,b,c,d)     VG_(do_syscall)((s),(a),(b),(c),(d),0,0)
-#define vgPlain_do_syscall5(s,a,b,c,d,e)   VG_(do_syscall)((s),(a),(b),(c),(d),(e),0)
-#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),(c),(d),(e),(f))
 
 extern void VG_(sigreturn)(void);
 
diff --git a/coregrind/linux/core_os.c b/coregrind/linux/core_os.c
index dc12410..18bf8c2 100644
--- a/coregrind/linux/core_os.c
+++ b/coregrind/linux/core_os.c
@@ -29,6 +29,7 @@
 */
 
 #include "core.h"
+#include "pub_core_libcbase.h"
 #include "pub_core_debuglog.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcprint.h"
@@ -140,6 +141,7 @@
    while (!i_am_the_only_thread()) {
       /* Let other thread(s) run */
       VG_(vg_yield)();
+      VG_(poll_signals)(self);
    }
    vg_assert(i_am_the_only_thread());
 }
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index 4eb20e2..343a4cb 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -590,7 +590,7 @@
    len = VG_PGROUNDUP(len);
 
    if (debug)
-      VG_(printf)("unmap_range(%p, %lu)\n", addr, len);
+      VG_(printf)("unmap_range(%p, %llu)\n", addr, (ULong)len);
    if (0) show_segments("unmap_range(BEFORE)");
    end = addr+len;
 
@@ -698,6 +698,8 @@
    static const Bool debug = False || mem_debug;
    Segment* s;
    Int      idx;
+   HChar*   stage2_suffix = "lib/valgrind/stage2";
+   Bool     is_stage2 = VG_(strstr)(filename, stage2_suffix) != NULL;
 
    if (debug)
       VG_(printf)(
@@ -707,6 +709,8 @@
          "                 filename='%s')\n",
          addr, (ULong)len, prot, flags, dev, ino, off, filename);
 
+   if (0) show_segments("before map_file_segment");
+
    /* Everything must be page-aligned */
    vg_assert(VG_IS_PAGE_ALIGNED(addr));
    len = VG_PGROUNDUP(len);
@@ -741,7 +745,9 @@
       file, then try reading symbols from it.
    */
    if (s->seginfo == NULL
-       && (addr+len < VG_(valgrind_base) || addr > VG_(valgrind_last))
+       && ( (addr+len < VG_(valgrind_base) || addr > VG_(valgrind_last))
+            || is_stage2
+          )
        && (flags & (SF_MMAP|SF_NOSYMS)) == SF_MMAP) {
       if (off == 0
 	  && s->fnIdx != -1
@@ -855,8 +861,8 @@
 
    if (debug) {
       VG_(printf)("\n\n");
-      VG_(printf)("find_map_space(%p, %lu, %d) ...\n",
-                  addr, len, for_client);
+      VG_(printf)("find_map_space(%p, %llu, %d) ...\n",
+                  addr, (ULong)len, for_client);
    }
 
    if (0) show_segments("find_map_space: start");
@@ -957,8 +963,8 @@
       ret = 0; /* not found */
 
    if (debug)
-      VG_(printf)("find_map_space(%p, %lu, %d) -> %p\n\n",
-                  addr, len, for_client, ret);
+      VG_(printf)("find_map_space(%p, %llu, %d) -> %p\n\n",
+                  addr, (ULong)len, for_client, ret);
 
    if (fixed) {
       vg_assert(ret == 0 || ret == addrOrig);
@@ -982,7 +988,7 @@
 void VG_(pad_address_space)(Addr start)
 {
    Addr     addr = (start == 0) ? VG_(client_base) : start;
-   void*    ret;
+   SysRes   ret;
 
    Int      i = 0;
    Segment* s = i >= segments_used ? NULL : &segments[i];
@@ -1010,7 +1016,7 @@
 void VG_(unpad_address_space)(Addr start)
 {
    Addr     addr = (start == 0) ? VG_(client_base) : start;
-   Int      ret;
+   SysRes   ret;
 
    Int      i = 0;
    Segment* s = i >= segments_used ? NULL : &segments[i];
@@ -1539,11 +1545,11 @@
       0,                         // ! seg not present
       1,                         // useable
    };
-   int ret = VG_(do_syscall3)(__NR_modify_ldt, 1, (UWord)&ldt, sizeof(ldt));
-   if (ret < 0) {
+   SysRes ret = VG_(do_syscall3)(__NR_modify_ldt, 1, (UWord)&ldt, sizeof(ldt));
+   if (ret.isError) {
       VG_(message)(Vg_UserMsg,
                    "Warning: ignoring --pointercheck=yes, "
-                   "because modify_ldt failed (errno=%d)", -ret);
+                   "because modify_ldt failed (errno=%d)", ret.val);
       return False;
    } else {
       return True;
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index 1ab10d3..2ed7f82 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -471,6 +471,56 @@
    #undef SORT
 }
 
+/* ---------------------------------------------------------------------
+   A function for doing syscalls.
+   ------------------------------------------------------------------ */
+
+#if defined(VGP_x86_linux)
+extern UInt do_syscall_x86_linux_WRK (
+          UInt syscall_no, 
+          UInt a1, UInt a2, UInt a3,
+          UInt a4, UInt a5, UInt a6
+       );
+asm(
+"do_syscall_x86_linux_WRK:\n"
+"	push	%esi\n"
+"	push	%edi\n"
+"	push	%ebx\n"
+"	push	%ebp\n"
+"	movl	16+ 4(%esp),%eax\n"
+"	movl	16+ 8(%esp),%ebx\n"
+"	movl	16+12(%esp),%ecx\n"
+"	movl	16+16(%esp),%edx\n"
+"	movl	16+20(%esp),%esi\n"
+"	movl	16+24(%esp),%edi\n"
+"	movl	16+28(%esp),%ebp\n"
+"	int	$0x80\n"
+"	popl	%ebp\n"
+"	popl	%ebx\n"
+"	popl	%edi\n"
+"	popl	%esi\n"
+"	ret\n"
+);
+#endif
+
+
+SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3, 
+                                      UWord a4, UWord a5, UWord a6 )
+{
+   SysRes res;
+
+#  if defined(VGP_x86_linux)
+   UInt eax = do_syscall_x86_linux_WRK(sysno,a1,a2,a3,a4,a5,a6);
+   res = VG_(mk_SysRes_x86_linux)( eax );
+#  else
+
+#    error VG_(do_syscall): unimplemented on this platform
+
+#  endif
+
+   return res;
+}
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 974dcdb..34ca579 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -33,7 +33,6 @@
 #include "pub_core_libcassert.h"
 #include "pub_core_libcfile.h"
 #include "pub_core_options.h"
-#include "pub_core_syscalls.h"      // For VG_(is_kerror)()
 #include "vki_unistd.h"
 
 /* ---------------------------------------------------------------------
@@ -67,86 +66,77 @@
 /* Returns -1 on failure. */
 Int VG_(open) ( const Char* pathname, Int flags, Int mode )
 {  
-   Int fd = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode);
-   return fd;
+   SysRes res = VG_(do_syscall3)(__NR_open, (UWord)pathname, flags, mode);
+   return res.isError ? -1 : res.val;
 }
 
 void VG_(close) ( Int fd )
 {
-   VG_(do_syscall1)(__NR_close, fd);
+   (void)VG_(do_syscall1)(__NR_close, fd);
 }
 
 Int VG_(read) ( Int fd, void* buf, Int count)
 {
-   Int res;
-   res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
-   return res;
+   SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
+   return res.isError ? -1 : res.val;
 }
 
 Int VG_(write) ( Int fd, const void* buf, Int count)
 {
-   Int res;
-   res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
-   return res;
+   SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
+   return res.isError ? -1 : res.val;
 }
 
 Int VG_(pipe) ( Int fd[2] )
 {
-   Int ret = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
-   return VG_(is_kerror)(ret) ? -1 : 0;
+   SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
+   return res.isError ? -1 : 0;
 }
 
 OffT VG_(lseek) ( Int fd, OffT offset, Int whence)
 {
-   Int res;
-   res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
-   if (VG_(is_kerror)(res)) res = -1;
-   return res;
+   SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
+   return res.isError ? (-1) : 0;
 }
 
 Int VG_(stat) ( Char* file_name, struct vki_stat* buf )
 {
-   Int res;
-   res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)buf);
-   return res;			/* return -ve error */
+   SysRes res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)buf);
+   return res.isError ? (-1) : 0;
 }
 
 Int VG_(fstat) ( Int fd, struct vki_stat* buf )
 {
-   Int res;
-   res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)buf);
-   return VG_(is_kerror)(res) ? (-1) : 0;
+   SysRes res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)buf);
+   return res.isError ? (-1) : 0;
 }
 
 Int VG_(dup2) ( Int oldfd, Int newfd )
 {
-   Int res;
-   res = VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
-   return VG_(is_kerror)(res) ? (-1) : res;
+   SysRes res = VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
+   return res.isError ? (-1) : res.val;
 }
 
 Int VG_(rename) ( Char* old_name, Char* new_name )
 {
-   Int res;
-   res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
-   return VG_(is_kerror)(res) ? (-1) : 0;
+   SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
+   return res.isError ? (-1) : 0;
 }
 
 Int VG_(unlink) ( Char* file_name )
 {
-   Int res;
-   res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
-   return VG_(is_kerror)(res) ? (-1) : 0;
+   SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
+   return res.isError ? (-1) : 0;
 }
 
 /* Nb: we do not allow the Linux extension which malloc()s memory for the
    buffer if buf==NULL, because we don't want Linux calling malloc() */
 Char* VG_(getcwd) ( Char* buf, SizeT size )
 {
-   Word res;
+   SysRes res;
    vg_assert(buf != NULL);
    res = VG_(do_syscall2)(__NR_getcwd, (UWord)buf, size);
-   return VG_(is_kerror)(res) ? ((Char*)NULL) : (Char*)res;
+   return res.isError ? ((Char*)NULL) : (Char*)res.val;
 }
 
 /* Alternative version that does allocate the memory.  Easier to use. */
@@ -170,20 +160,18 @@
 
 Int VG_(readlink) (Char* path, Char* buf, UInt bufsiz)
 {
-   Int res;
+   SysRes res;
    /* res = readlink( path, buf, bufsiz ); */
    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
-   if (VG_(is_kerror)(res)) res = -1;
-   return res;
+   return res.isError ? -1 : res.val;
 }
 
 Int VG_(getdents) (UInt fd, struct vki_dirent *dirp, UInt count)
 {
-   Int res;
+   SysRes res;
    /* res = getdents( fd, dirp, count ); */
    res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
-   if (VG_(is_kerror)(res)) res = -1;
-   return res;
+   return res.isError ? -1 : res.val;
 }
 
 /* ---------------------------------------------------------------------
@@ -309,133 +297,119 @@
 #  undef GET_CH
 }
 
-
 static
 Int my_socket ( Int domain, Int type, Int protocol )
 {
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
-   I_die_here;
-#else
-   Int res;
-   UWord args[3];
+#  if defined(VGP_x86_linux)
+   SysRes res;
+   UWord  args[3];
    args[0] = domain;
    args[1] = type;
    args[2] = protocol;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
-   if (VG_(is_kerror)(res)) 
-      res = -1;
-   return res;
-#endif
+   return res.isError ? -1 : res.val;
+#  else
+   // AMD64/Linux doesn't define __NR_socketcall... see comment above
+   // VG_(sigpending)() for more details.
+   I_die_here;
+#  endif
 }
 
 static
 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, 
                  Int addrlen )
 {
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
-   I_die_here;
-#else
-   Int res;
-   UWord args[3];
+#  if defined(VGP_x86_linux)
+   SysRes res;
+   UWord  args[3];
    args[0] = sockfd;
    args[1] = (UWord)serv_addr;
    args[2] = addrlen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
-   if (VG_(is_kerror)(res)) 
-      res = -1;
-   return res;
-#endif
+   return res.isError ? -1 : res.val;
+#  else
+   // AMD64/Linux doesn't define __NR_socketcall... see comment above
+   // VG_(sigpending)() for more details.
+   I_die_here;
+#  endif
 }
 
 Int VG_(write_socket)( Int sd, void *msg, Int count )
 {
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
-   I_die_here;
-#else
    /* This is actually send(). */
-
    /* Requests not to send SIGPIPE on errors on stream oriented
       sockets when the other end breaks the connection. The EPIPE
       error is still returned. */
    Int flags = VKI_MSG_NOSIGNAL;
 
-   Int res;
-   UWord args[4];
+#  if defined(VGP_x86_linux)
+   SysRes res;
+   UWord  args[4];
    args[0] = sd;
    args[1] = (UWord)msg;
    args[2] = count;
    args[3] = flags;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
-   if (VG_(is_kerror)(res)) 
-      res = -1;
-   return res;
-#endif
+   return res.isError ? -1 : res.val;
+#  else
+   // AMD64/Linux doesn't define __NR_socketcall... see comment above
+   // VG_(sigpending)() for more details.
+   I_die_here;
+#  endif
 }
 
 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
 {
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
-   I_die_here;
-#else
-   Int res;
-   UWord args[3];
+#  if defined(VGP_x86_linux)
+   SysRes res;
+   UWord  args[3];
    args[0] = sd;
    args[1] = (UWord)name;
    args[2] = (UWord)namelen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
-   if(VG_(is_kerror)(res))
-      res = -1;
-   return res;
-#endif
+   return res.isError ? -1 : res.val;
+#  else
+   // AMD64/Linux doesn't define __NR_socketcall... see comment above
+   // VG_(sigpending)() for more details.
+   I_die_here;
+#  endif
 }
 
 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
 {
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
-   I_die_here;
-#else
-   Int res;
-   UWord args[3];
+#  if defined(VGP_x86_linux)
+   SysRes res;
+   UWord  args[3];
    args[0] = sd;
    args[1] = (UWord)name;
    args[2] = (UWord)namelen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
-   if(VG_(is_kerror)(res))
-      res = -1;
-   return res;
-#endif
+   return res.isError ? -1 : res.val;
+#  else
+   // AMD64/Linux doesn't define __NR_socketcall... see comment above
+   // VG_(sigpending)() for more details.
+   I_die_here;
+#  endif
 }
 
 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
                       Int *optlen)
 {
-// AMD64/Linux doesn't define __NR_socketcall... see comment above
-// VG_(sigpending)() for more details.
-#ifdef __amd64__
-   I_die_here;
-#else
-   Int res;
-   UWord args[5];
+#  if defined(VGP_x86_linux)
+   SysRes res;
+   UWord  args[5];
    args[0] = sd;
    args[1] = level;
    args[2] = optname;
    args[3] = (UWord)optval;
    args[4] = (UWord)optlen;
    res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
-   if(VG_(is_kerror)(res))
-      res = -1;
-   return res;
-#endif
+   return res.isError ? -1 : res.val;
+#  else
+   I_die_here;
+   // AMD64/Linux doesn't define __NR_socketcall... see comment above
+   // VG_(sigpending)() for more details.
+#  endif
 }
 
 
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index 9be79d5..64e297c 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -338,7 +338,8 @@
 
    if (VG_(clo_trace_sched)) {
       Char buf[50];
-      VG_(sprintf)(buf, "now sleeping in state %s", name_of_thread_state(sleepstate));
+      VG_(sprintf)(buf, "now sleeping in state %s", 
+                        name_of_thread_state(sleepstate));
       print_sched_event(tid, buf);
    }
 }
@@ -410,8 +411,6 @@
       VG_(nanosleep)(&ts);
 
    VG_(set_running)(tid);
-
-   VG_(poll_signals)(tid);	/* something might have happened */
 }
 
 
@@ -566,8 +565,6 @@
       until the caller is finally done with the thread stack. */
    VG_(threads)[tid].status               = VgTs_Zombie;
 
-   VG_(threads)[tid].syscallno = -1;
-
    VG_(sigemptyset)(&VG_(threads)[tid].sig_mask);
    VG_(sigemptyset)(&VG_(threads)[tid].tmp_sig_mask);
 
@@ -613,6 +610,7 @@
       if (tid != me) {
          mostly_clear_thread_record(tid);
 	 VG_(threads)[tid].status = VgTs_Empty;
+         VG_(clear_syscallInfo)(tid);
       }
    }
 
@@ -908,6 +906,8 @@
             "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
 
       VG_(threads)[tid].exitreason = src;
+      if (src == VgSrc_FatalSig)
+         VG_(threads)[tid].os_state.fatalsig = VKI_SIGKILL;
       VG_(kill_thread)(tid);
    }
 }
diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c
index e126ec9..5f3adc5 100644
--- a/coregrind/m_signals.c
+++ b/coregrind/m_signals.c
@@ -124,7 +124,9 @@
 #  define VGP_UCONTEXT_STACK_PTR(uc)      ((uc)->uc_mcontext.esp)
 #  define VGP_UCONTEXT_FRAME_PTR(uc)      ((uc)->uc_mcontext.ebp)
 #  define VGP_UCONTEXT_SYSCALL_NUM(uc)    ((uc)->uc_mcontext.eax)
-#  define VGP_UCONTEXT_SYSCALL_RET(uc)    ((uc)->uc_mcontext.eax)
+#  define VGP_UCONTEXT_SYSCALL_SYSRES(uc)                       \
+      /* Convert the value in uc_mcontext.eax into a SysRes. */ \
+      VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
 #elif defined(VGP_amd64_linux)
 #  define VGP_UCONTEXT_INSTR_PTR(uc)      ((uc)->uc_mcontext.rip)
 #  define VGP_UCONTEXT_STACK_PTR(uc)      ((uc)->uc_mcontext.rsp)
@@ -327,10 +329,11 @@
 
       /* SA_ONESHOT: ignore client setting */
       
-      /* SA_RESTART: ignore client setting and always set it for us
-	 (even though we never rely on the kernel to restart a
+      /* SA_RESTART: ignore client setting and always set it for us.
+	 Though we never rely on the kernel to restart a
 	 syscall, we observe whether it wanted to restart the syscall
-	 or not, which helps VGA_(interrupted_syscall)()) */
+	 or not, which is needed by 
+         VG_(fixup_guest_state_after_syscall_interrupted) */
       skss_flags |= VKI_SA_RESTART;
 
       /* SA_NOMASK: ignore it */
@@ -458,7 +461,7 @@
 }
 
 
-Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
+SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
 {
    Addr m_SP;
 
@@ -479,18 +482,18 @@
 
    if (ss != NULL) {
       if (on_sig_stack(tid, STACK_PTR(VG_(threads)[tid].arch))) {
-         return -VKI_EPERM;
+         return VG_(mk_SysRes_Error)( VKI_EPERM );
       }
       if (ss->ss_flags != VKI_SS_DISABLE 
           && ss->ss_flags != VKI_SS_ONSTACK 
           && ss->ss_flags != 0) {
-         return -VKI_EINVAL;
+         return VG_(mk_SysRes_Error)( VKI_EINVAL );
       }
       if (ss->ss_flags == VKI_SS_DISABLE) {
          VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
       } else {
          if (ss->ss_size < VKI_MINSIGSTKSZ) {
-            return -VKI_ENOMEM;
+            return VG_(mk_SysRes_Error)( VKI_ENOMEM );
          }
 
 	 VG_(threads)[tid].altstack.ss_sp    = ss->ss_sp;
@@ -498,13 +501,13 @@
 	 VG_(threads)[tid].altstack.ss_flags = 0;
       }
    }
-   return 0;
+   return VG_(mk_SysRes_Success)( 0 );
 }
 
 
-Int VG_(do_sys_sigaction) ( Int signo, 
-			    const struct vki_sigaction *new_act, 
-			    struct vki_sigaction *old_act )
+SysRes VG_(do_sys_sigaction) ( Int signo, 
+                               const struct vki_sigaction *new_act, 
+                               struct vki_sigaction *old_act )
 {
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugExtraMsg, 
@@ -523,7 +526,8 @@
    /* don't let them use our signals */
    if ( (signo > VKI_SIGVGRTUSERMAX)
 	&& new_act
-	&& !(new_act->ksa_handler == VKI_SIG_DFL || new_act->ksa_handler == VKI_SIG_IGN) )
+	&& !(new_act->ksa_handler == VKI_SIG_DFL 
+             || new_act->ksa_handler == VKI_SIG_IGN) )
       goto bad_signo_reserved;
 
    /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
@@ -556,7 +560,7 @@
    if (new_act) {
       handle_SCSS_change( False /* lazy update */ );
    }
-   return 0;
+   return VG_(mk_SysRes_Success)( 0 );
 
   bad_signo:
    if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
@@ -565,7 +569,7 @@
                    "Warning: bad signal number %d in sigaction()", 
                    signo);
    }
-   return -VKI_EINVAL;
+   return VG_(mk_SysRes_Error)( VKI_EINVAL );
 
   bad_signo_reserved:
    if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
@@ -577,7 +581,7 @@
 		   "         the %s signal is used internally by Valgrind", 
 		   signame(signo));
    }
-   return -VKI_EINVAL;
+   return VG_(mk_SysRes_Error)( VKI_EINVAL );
 
   bad_sigkill_or_sigstop:
    if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
@@ -589,7 +593,7 @@
 		   "         the %s signal is uncatchable", 
 		   signame(signo));
    }
-   return -VKI_EINVAL;
+   return VG_(mk_SysRes_Error)( VKI_EINVAL );
 }
 
 
@@ -655,10 +659,10 @@
 }
 
 
-int VG_(do_sys_sigprocmask) ( ThreadId tid,
-                               Int how, 
-                               vki_sigset_t* set,
-                               vki_sigset_t* oldset )
+SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
+                                 Int how, 
+                                 vki_sigset_t* set,
+                                 vki_sigset_t* oldset )
 {
    switch(how) {
    case VKI_SIG_BLOCK:
@@ -666,13 +670,12 @@
    case VKI_SIG_SETMASK:
       vg_assert(VG_(is_valid_tid)(tid));
       do_setmask ( tid, how, set, oldset );
-      VG_(poll_signals)(tid);	/* look for any newly deliverable signals */
-      return 0;
+      return VG_(mk_SysRes_Success)( 0 );
 
    default:
       VG_(message)(Vg_DebugMsg, 
                   "sigprocmask: unknown 'how' field %d", how);
-      return -VKI_EINVAL;
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 }
 
@@ -1611,11 +1614,13 @@
 		   sigNo, tid, info->si_code);
 
    /* Update thread state properly */
-   VGP_(interrupted_syscall)(tid, 
-                             VGP_UCONTEXT_INSTR_PTR(uc), 
-                             VGP_UCONTEXT_SYSCALL_NUM(uc), 
-                             VGP_UCONTEXT_SYSCALL_RET(uc), 
-			     !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART));
+   VG_(fixup_guest_state_after_syscall_interrupted)(
+      tid, 
+      VGP_UCONTEXT_INSTR_PTR(uc), 
+      VGP_UCONTEXT_SYSCALL_NUM(uc), 
+      VGP_UCONTEXT_SYSCALL_SYSRES(uc),  
+      !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
+   );
 
    /* Set up the thread's state to deliver a signal */
    if (!is_sig_ign(info->si_signo))
@@ -1985,7 +1990,8 @@
    /* If there was nothing queued, ask the kernel for a pending signal */
    if (sip == NULL && VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
       if (VG_(clo_trace_signals))
-	 VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d", si.si_signo, tid);
+	 VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d "
+                                   "for thread %d", si.si_signo, tid);
       sip = &si;
    }
 
diff --git a/coregrind/m_syscalls/Makefile.am b/coregrind/m_syscalls/Makefile.am
index 796a082..51c7db1 100644
--- a/coregrind/m_syscalls/Makefile.am
+++ b/coregrind/m_syscalls/Makefile.am
@@ -5,7 +5,8 @@
 	README_SYSCALLS.txt
 
 noinst_HEADERS = \
-	priv_syscalls.h \
+	priv_types_n_macros.h \
+	priv_syscalls-generic.h \
 	priv_syscalls-linux.h \
 	priv_syscalls-amd64-linux.h \
 	priv_syscalls-arm-linux.h \
@@ -15,6 +16,7 @@
 
 libsyscalls_a_SOURCES = \
 	syscall-@VG_PLATFORM@.S \
-	syscalls.c \
+	syscalls-generic.c \
 	syscalls-@VG_OS@.c \
-	syscalls-@VG_PLATFORM@.c
+	syscalls-@VG_PLATFORM@.c \
+	syscalls-main.c
diff --git a/coregrind/m_syscalls/README_SYSCALLS.txt b/coregrind/m_syscalls/README_SYSCALLS.txt
index 5c12cf7..0600693 100644
--- a/coregrind/m_syscalls/README_SYSCALLS.txt
+++ b/coregrind/m_syscalls/README_SYSCALLS.txt
@@ -1 +1,14 @@
-(put useful notes about this module in here)
+
+This module handles the complex business of handing system calls off
+to the host and then fixing up the guest state accordingly.  It
+interacts complicatedly with signals and to a less extent threads.
+
+There are some important caveats regarding how to write the PRE and
+POST wrappers for syscalls.  It is important to observe these, else
+you will have to track down almost impossibly obscure bugs.  These
+caveats are described in comments at the top of syscalls-main.c.
+
+The main file is syscalls-main.c.  It contains all the driver logic
+and a great deal of commentary.  The wrappers themselves live in
+syscalls-generic.c, syscalls-${OS}.c and syscalls-${PLATFORM}.c.
+
diff --git a/coregrind/m_syscalls/priv_syscalls-generic.h b/coregrind/m_syscalls/priv_syscalls-generic.h
new file mode 100644
index 0000000..e695cf4
--- /dev/null
+++ b/coregrind/m_syscalls/priv_syscalls-generic.h
@@ -0,0 +1,324 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Private syscalls header.                     priv_syscalls.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PRIV_SYSCALLS_GENERIC_H
+#define __PRIV_SYSCALLS_GENERIC_H
+
+/* requires #include "priv_types_n_macros.h" */
+
+
+// Return true if address range entirely contained within client
+// address space.
+extern
+Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
+                            const Char *syscallname);
+
+// Return true if we're allowed to use or create this fd.
+extern
+Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft);
+
+extern
+void VG_(record_fd_open)(ThreadId tid, Int fd, char *pathname);
+
+// Used when killing threads -- we must not kill a thread if it's the thread
+// that would do Valgrind's final cleanup and output.
+extern
+Bool VG_(do_sigkill)(Int pid, Int tgid);
+
+/* So that it can be seen from syscalls-x86-linux.c. */
+extern 
+void VG_(mmap_segment) ( Addr a, SizeT len, UInt prot, 
+                         UInt mm_flags, Int fd, ULong offset );
+
+
+DECL_TEMPLATE(generic,sys_ni_syscall);            // * P -- unimplemented
+DECL_TEMPLATE(generic,sys_exit);
+DECL_TEMPLATE(generic,sys_fork);
+DECL_TEMPLATE(generic,sys_read);
+DECL_TEMPLATE(generic,sys_write);
+DECL_TEMPLATE(generic,sys_open);
+DECL_TEMPLATE(generic,sys_close);
+DECL_TEMPLATE(generic,sys_waitpid);
+DECL_TEMPLATE(generic,sys_creat);
+DECL_TEMPLATE(generic,sys_link);
+DECL_TEMPLATE(generic,sys_unlink);
+DECL_TEMPLATE(generic,sys_execve);    // (*??) P
+DECL_TEMPLATE(generic,sys_chdir);
+DECL_TEMPLATE(generic,sys_time);
+DECL_TEMPLATE(generic,sys_mknod);
+DECL_TEMPLATE(generic,sys_chmod);
+DECL_TEMPLATE(generic,sys_lseek);
+DECL_TEMPLATE(generic,sys_getpid);
+DECL_TEMPLATE(generic,sys_alarm);
+DECL_TEMPLATE(generic,sys_pause);
+DECL_TEMPLATE(generic,sys_utime);
+DECL_TEMPLATE(generic,sys_access);
+DECL_TEMPLATE(generic,sys_kill);
+DECL_TEMPLATE(generic,sys_rename);
+DECL_TEMPLATE(generic,sys_mkdir);
+DECL_TEMPLATE(generic,sys_rmdir);
+DECL_TEMPLATE(generic,sys_dup);
+DECL_TEMPLATE(generic,sys_times);
+DECL_TEMPLATE(generic,sys_fcntl);        // POSIX (but complicated)
+DECL_TEMPLATE(generic,sys_setpgid);
+DECL_TEMPLATE(generic,sys_umask);
+DECL_TEMPLATE(generic,sys_dup2);
+DECL_TEMPLATE(generic,sys_getppid);
+DECL_TEMPLATE(generic,sys_getpgrp);
+DECL_TEMPLATE(generic,sys_setsid);
+DECL_TEMPLATE(generic,sys_munmap);
+DECL_TEMPLATE(generic,sys_truncate);
+DECL_TEMPLATE(generic,sys_ftruncate);
+DECL_TEMPLATE(generic,sys_fchmod);
+DECL_TEMPLATE(generic,sys_msync);
+DECL_TEMPLATE(generic,sys_readv);
+DECL_TEMPLATE(generic,sys_writev);
+DECL_TEMPLATE(generic,sys_getsid);
+DECL_TEMPLATE(generic,sys_fdatasync);
+DECL_TEMPLATE(generic,sys_mlock);
+DECL_TEMPLATE(generic,sys_munlock);
+DECL_TEMPLATE(generic,sys_mlockall);
+DECL_TEMPLATE(generic,sys_munlockall);
+DECL_TEMPLATE(generic,sys_sched_setparam);
+DECL_TEMPLATE(generic,sys_sched_getparam);
+DECL_TEMPLATE(generic,sys_sched_rr_get_interval);
+DECL_TEMPLATE(generic,sys_sched_setscheduler);
+DECL_TEMPLATE(generic,sys_sched_getscheduler);
+DECL_TEMPLATE(generic,sys_sched_yield);
+DECL_TEMPLATE(generic,sys_sched_get_priority_max);
+DECL_TEMPLATE(generic,sys_sched_get_priority_min);
+DECL_TEMPLATE(generic,sys_nanosleep);
+DECL_TEMPLATE(generic,sys_mremap);    // POSIX, but Linux arg order may be odd
+DECL_TEMPLATE(generic,sys_getuid);
+DECL_TEMPLATE(generic,sys_getgid);
+DECL_TEMPLATE(generic,sys_geteuid);
+DECL_TEMPLATE(generic,sys_getegid);
+DECL_TEMPLATE(generic,sys_getpgid);
+DECL_TEMPLATE(generic,sys_fsync);
+DECL_TEMPLATE(generic,sys_wait4);
+DECL_TEMPLATE(generic,sys_mprotect);
+DECL_TEMPLATE(generic,sys_sigprocmask);
+DECL_TEMPLATE(generic,sys_timer_create);    // Linux: varies across archs?
+DECL_TEMPLATE(generic,sys_timer_settime);
+DECL_TEMPLATE(generic,sys_timer_gettime);
+DECL_TEMPLATE(generic,sys_timer_getoverrun);
+DECL_TEMPLATE(generic,sys_timer_delete);
+DECL_TEMPLATE(generic,sys_clock_settime);
+DECL_TEMPLATE(generic,sys_clock_gettime);
+DECL_TEMPLATE(generic,sys_clock_getres);
+DECL_TEMPLATE(generic,sys_clock_nanosleep);
+DECL_TEMPLATE(generic,sys_getcwd);
+DECL_TEMPLATE(generic,sys_symlink);
+DECL_TEMPLATE(generic,sys_getgroups);
+DECL_TEMPLATE(generic,sys_setgroups);             // SVr4, SVID, X/OPEN, 4.3BSD
+DECL_TEMPLATE(generic,sys_chown);
+DECL_TEMPLATE(generic,sys_setuid);
+DECL_TEMPLATE(generic,sys_gettimeofday);
+DECL_TEMPLATE(generic,sys_madvise);
+DECL_TEMPLATE(generic,sys_sigpending);
+
+// These ones aren't POSIX, but are in some standard and look reasonably
+// generic, and are the same for all architectures under Linux.
+DECL_TEMPLATE(generic,sys_nice);      // SVr4, SVID EXT, AT&T, X/OPEN, BSD 4.3
+DECL_TEMPLATE(generic,sys_sync);      // SVr4, SVID, X/OPEN, BSD 4.3
+DECL_TEMPLATE(generic,sys_brk);       // 4.3BSD
+DECL_TEMPLATE(generic,sys_acct);      // SVR4, non-POSIX
+DECL_TEMPLATE(generic,sys_chroot);    // SVr4, SVID, 4.4BSD, X/OPEN
+DECL_TEMPLATE(generic,sys_readlink);  // X/OPEN, 4.4BSD
+DECL_TEMPLATE(generic,sys_fchdir);    // SVr4, SVID, POSIX, X/OPEN, 4.4BSD
+DECL_TEMPLATE(generic,sys_getdents);  // SVr4,SVID
+DECL_TEMPLATE(generic,sys_select);    // 4.4BSD
+DECL_TEMPLATE(generic,sys_flock);     // 4.4BSD
+DECL_TEMPLATE(generic,sys_poll);      // XPG4-UNIX
+DECL_TEMPLATE(generic,sys_getrusage); // SVr4, 4.3BSD
+DECL_TEMPLATE(generic,sys_stime);	    // SVr4, SVID, X/OPEN
+DECL_TEMPLATE(generic,sys_settimeofday); // SVr4, 4.3BSD (non-POSIX)
+DECL_TEMPLATE(generic,sys_getpriority);  // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_setpriority);  // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_setitimer);    // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_getitimer);    // SVr4, 4.4BSD
+DECL_TEMPLATE(generic,sys_setreuid);     // 4.3BSD
+DECL_TEMPLATE(generic,sys_setregid);     // 4.3BSD
+DECL_TEMPLATE(generic,sys_fchown);       // SVr4,4.3BSD
+DECL_TEMPLATE(generic,sys_setgid);       // SVr4,SVID
+DECL_TEMPLATE(generic,sys_utimes);       // 4.3BSD
+
+// These ones may be Linux specific... not sure.  They use 16-bit gid_t and
+// uid_t types.  The similarly named (minus the "16" suffix) ones below use
+// 32-bit versions of these types.
+DECL_TEMPLATE(generic,sys_setuid16);              // ## P
+DECL_TEMPLATE(generic,sys_getuid16);              // ## P
+DECL_TEMPLATE(generic,sys_setgid16);              // ## SVr4,SVID
+DECL_TEMPLATE(generic,sys_getgid16);              // ## P
+DECL_TEMPLATE(generic,sys_geteuid16);             // ## P
+DECL_TEMPLATE(generic,sys_getegid16);             // ## P
+DECL_TEMPLATE(generic,sys_setreuid16);            // ## BSD4.3
+DECL_TEMPLATE(generic,sys_setregid16);            // ## BSD4.3
+DECL_TEMPLATE(generic,sys_getgroups16);           // ## P
+DECL_TEMPLATE(generic,sys_setgroups16);           // ## SVr4, SVID, X/OPEN, 4.3BSD
+DECL_TEMPLATE(generic,sys_fchown16);              // ## SVr4,BSD4.3
+DECL_TEMPLATE(generic,sys_chown16);               // ## P
+
+// Some archs on Linux do not match the generic wrapper for sys_pipe().
+DECL_TEMPLATE(generic,sys_pipe);
+
+// May not be generic for every architecture under Linux.
+DECL_TEMPLATE(generic,sys_sigaction);             // (x86) P
+
+// Funny names, not sure...
+DECL_TEMPLATE(generic,sys_newstat);               // * P
+DECL_TEMPLATE(generic,sys_newlstat);              // *
+DECL_TEMPLATE(generic,sys_newfstat);              // * P (SVr4,BSD4.3)
+
+// For the remainder, not really sure yet
+DECL_TEMPLATE(generic,sys_ptrace);                // (x86?) (almost-P)
+DECL_TEMPLATE(generic,sys_sigsuspend);            // POSIX, but L (proto varies across archs)
+DECL_TEMPLATE(generic,sys_setrlimit);             // SVr4, 4.3BSD
+DECL_TEMPLATE(generic,sys_ioctl);                 // x86? (various)
+DECL_TEMPLATE(generic,sys_old_getrlimit);         // SVr4, 4.3BSD L?
+DECL_TEMPLATE(generic,sys_statfs);                // * L?
+DECL_TEMPLATE(generic,sys_fstatfs);               // * L?
+DECL_TEMPLATE(generic,sys_iopl);                  // (x86/amd64) L
+DECL_TEMPLATE(generic,sys_ipc);                   // (x86) L
+DECL_TEMPLATE(generic,sys_newuname);              // * P
+DECL_TEMPLATE(generic,sys_init_module);           // * L?
+DECL_TEMPLATE(generic,sys_quotactl);              // * (?)
+DECL_TEMPLATE(generic,sys_rt_sigaction);          // (x86) ()
+DECL_TEMPLATE(generic,sys_rt_sigprocmask);        // * ?
+DECL_TEMPLATE(generic,sys_rt_sigpending);         // * ?
+DECL_TEMPLATE(generic,sys_rt_sigtimedwait);       // * ?
+DECL_TEMPLATE(generic,sys_rt_sigqueueinfo);       // * ?
+DECL_TEMPLATE(generic,sys_rt_sigsuspend);         // () ()
+DECL_TEMPLATE(generic,sys_pread64);               // * (Unix98?)
+DECL_TEMPLATE(generic,sys_pwrite64);              // * (Unix98?)
+DECL_TEMPLATE(generic,sys_capget);                // * L?
+DECL_TEMPLATE(generic,sys_capset);                // * L?
+DECL_TEMPLATE(generic,sys_sigaltstack);           // (x86) (XPG4-UNIX)
+DECL_TEMPLATE(generic,sys_getpmsg);               // (?) (?)
+DECL_TEMPLATE(generic,sys_putpmsg);               // (?) (?)
+DECL_TEMPLATE(generic,sys_getrlimit);             // * (?)
+DECL_TEMPLATE(generic,sys_mmap2);                 // (x86?) P?
+DECL_TEMPLATE(generic,sys_truncate64);            // %% (P?)
+DECL_TEMPLATE(generic,sys_ftruncate64);           // %% (P?)
+DECL_TEMPLATE(generic,sys_lchown);                // * (L?)
+DECL_TEMPLATE(generic,sys_mincore);               // * L?
+DECL_TEMPLATE(generic,sys_getdents64);            // * (SVr4,SVID?)
+DECL_TEMPLATE(generic,sys_fcntl64);               // * P?
+DECL_TEMPLATE(generic,sys_setxattr);              // * L?
+DECL_TEMPLATE(generic,sys_lsetxattr);             // * L?
+DECL_TEMPLATE(generic,sys_fsetxattr);             // * L?
+DECL_TEMPLATE(generic,sys_getxattr);              // * L?
+DECL_TEMPLATE(generic,sys_lgetxattr);             // * L?
+DECL_TEMPLATE(generic,sys_fgetxattr);             // * L?
+DECL_TEMPLATE(generic,sys_listxattr);             // * L?
+DECL_TEMPLATE(generic,sys_llistxattr);            // * L?
+DECL_TEMPLATE(generic,sys_flistxattr);            // * L?
+DECL_TEMPLATE(generic,sys_removexattr);           // * L?
+DECL_TEMPLATE(generic,sys_lremovexattr);          // * L?
+DECL_TEMPLATE(generic,sys_fremovexattr);          // * L?
+DECL_TEMPLATE(generic,sys_sched_setaffinity);     // * L?
+DECL_TEMPLATE(generic,sys_sched_getaffinity);     // * L?
+DECL_TEMPLATE(generic,sys_lookup_dcookie);        // (*/32/64) L
+DECL_TEMPLATE(generic,sys_set_tid_address);       // * ?
+DECL_TEMPLATE(generic,sys_statfs64);              // * (?)
+DECL_TEMPLATE(generic,sys_fstatfs64);             // * (?)
+DECL_TEMPLATE(generic,sys_mq_open);               // * P?
+DECL_TEMPLATE(generic,sys_mq_unlink);             // * P?
+DECL_TEMPLATE(generic,sys_mq_timedsend);          // * P?
+DECL_TEMPLATE(generic,sys_mq_timedreceive);       // * P?
+DECL_TEMPLATE(generic,sys_mq_notify);             // * P?
+DECL_TEMPLATE(generic,sys_mq_getsetattr);         // * P?
+
+
+
+/* ---------------------------------------------------------------------
+   Wrappers for sockets and ipc-ery.  These are split into standalone
+   procedures because x86-linux hides them inside multiplexors
+   (sys_socketcall and sys_ipc).
+   ------------------------------------------------------------------ */
+
+#define TId ThreadId
+#define UW  UWord
+#define SR  SysRes
+
+extern void   VG_(generic_PRE_sys_socketpair)   ( TId, UW, UW, UW, UW );
+extern SysRes VG_(generic_POST_sys_socketpair)  ( TId, SR, UW, UW, UW, UW );
+extern SysRes VG_(generic_POST_sys_socket)      ( TId, SR );
+extern void   VG_(generic_PRE_sys_bind)         ( TId, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_accept)       ( TId, UW, UW, UW );
+extern SysRes VG_(generic_POST_sys_accept)      ( TId, SR, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_sendto)       ( TId, UW, UW, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_send)         ( TId, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_recvfrom)     ( TId, UW, UW, UW, UW, UW, UW );
+extern void   VG_(generic_POST_sys_recvfrom)    ( TId, SR, UW, UW, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_recv)         ( TId, UW, UW, UW );
+extern void   VG_(generic_POST_sys_recv)        ( TId, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_connect)      ( TId, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_setsockopt)   ( TId, UW, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_getsockopt)   ( TId, UW, UW, UW, UW, UW );
+extern void   VG_(generic_POST_sys_getsockopt)  ( TId, SR, UW, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_getsockname)  ( TId, UW, UW, UW );
+extern void   VG_(generic_POST_sys_getsockname) ( TId, SR, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_getpeername)  ( TId, UW, UW, UW );
+extern void   VG_(generic_POST_sys_getpeername) ( TId, SR, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_sendmsg)      ( TId, UW, UW );
+extern void   VG_(generic_PRE_sys_recvmsg)      ( TId, UW, UW );
+extern void   VG_(generic_POST_sys_recvmsg)     ( TId, UW, UW );
+
+extern void   VG_(generic_PRE_sys_semop)        ( TId, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_semtimedop)   ( TId, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_semctl)       ( TId, UW, UW, UW, UW );
+extern void   VG_(generic_POST_sys_semctl)      ( TId, UW, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_msgsnd)       ( TId, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_msgrcv)       ( TId, UW, UW, UW, UW, UW );
+extern void   VG_(generic_POST_sys_msgrcv)      ( TId, UW, UW, UW, UW, UW, UW );
+extern void   VG_(generic_PRE_sys_msgctl)       ( TId, UW, UW, UW );
+extern void   VG_(generic_POST_sys_msgctl)      ( TId, UW, UW, UW, UW );
+extern UWord  VG_(generic_PRE_sys_shmat)        ( TId, UW, UW, UW );
+extern void   VG_(generic_POST_sys_shmat)       ( TId, UW, UW, UW, UW );
+extern Bool   VG_(generic_PRE_sys_shmdt)        ( TId, UW );
+extern void   VG_(generic_POST_sys_shmdt)       ( TId, UW, UW );
+extern void   VG_(generic_PRE_sys_shmctl)       ( TId, UW, UW, UW );
+extern void   VG_(generic_POST_sys_shmctl)      ( TId, UW, UW, UW, UW );
+
+#undef TId
+#undef UW
+#undef SR
+
+
+/////////////////////////////////////////////////////////////////
+
+
+#endif   // __PRIV_SYSCALLS_GENERIC_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                                          ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_syscalls/priv_syscalls-linux.h b/coregrind/m_syscalls/priv_syscalls-linux.h
index 86223cf..7747196 100644
--- a/coregrind/m_syscalls/priv_syscalls-linux.h
+++ b/coregrind/m_syscalls/priv_syscalls-linux.h
@@ -31,68 +31,60 @@
 #ifndef __PRIV_SYSCALLS_LINUX_H
 #define __PRIV_SYSCALLS_LINUX_H
 
-// Macros for adding Linux-specific, arch-independent wrappers to a syscall
-// table.
-#define LINX_(const, name)    SYS_WRAPPER_ENTRY_X_(vgOS_linux, const, name) 
-#define LINXY(const, name)    SYS_WRAPPER_ENTRY_XY(vgOS_linux, const, name)
+/* requires #include "priv_types_n_macros.h" */
 
-// The following syscall wrappers are Linux-specific, but arch-independent.
-#define LINUX_SYSCALL_WRAPPER(x) \
-   extern UInt VGO_(linux_##x##_flags); \
-   extern void VGO_(linux_##x##_before)(ThreadId tid, ThreadState *tst); \
-   extern void VGO_(linux_##x##_after) (ThreadId tid, ThreadState *tst)
 
-LINUX_SYSCALL_WRAPPER(sys_exit_group);
+DECL_TEMPLATE(linux,sys_exit_group);
 
-LINUX_SYSCALL_WRAPPER(sys_mount);
-LINUX_SYSCALL_WRAPPER(sys_oldumount);
-LINUX_SYSCALL_WRAPPER(sys_umount);
+DECL_TEMPLATE(linux,sys_mount);
+DECL_TEMPLATE(linux,sys_oldumount);
+DECL_TEMPLATE(linux,sys_umount);
 
-LINUX_SYSCALL_WRAPPER(sys_llseek);
-LINUX_SYSCALL_WRAPPER(sys_adjtimex);
+DECL_TEMPLATE(linux,sys_llseek);
+DECL_TEMPLATE(linux,sys_adjtimex);
 
-LINUX_SYSCALL_WRAPPER(sys_setfsuid16);
-LINUX_SYSCALL_WRAPPER(sys_setfsgid16);
-LINUX_SYSCALL_WRAPPER(sys_setresuid16);  // man page says "non-standard";
-LINUX_SYSCALL_WRAPPER(sys_getresuid16);
-LINUX_SYSCALL_WRAPPER(sys_setresgid16);  // man page says "non-standard"
-LINUX_SYSCALL_WRAPPER(sys_getresgid16);
+DECL_TEMPLATE(linux,sys_setfsuid16);
+DECL_TEMPLATE(linux,sys_setfsgid16);
+DECL_TEMPLATE(linux,sys_setresuid16);  // man page says "non-standard";
+DECL_TEMPLATE(linux,sys_getresuid16);
+DECL_TEMPLATE(linux,sys_setresgid16);  // man page says "non-standard"
+DECL_TEMPLATE(linux,sys_getresgid16);
 
-LINUX_SYSCALL_WRAPPER(sys_setfsuid);
-LINUX_SYSCALL_WRAPPER(sys_setfsgid);
-LINUX_SYSCALL_WRAPPER(sys_setresuid);    // man page says "non-standard"
-LINUX_SYSCALL_WRAPPER(sys_getresuid);
-LINUX_SYSCALL_WRAPPER(sys_setresgid);    // man page says "non-standard"
-LINUX_SYSCALL_WRAPPER(sys_getresgid);
+DECL_TEMPLATE(linux,sys_setfsuid);
+DECL_TEMPLATE(linux,sys_setfsgid);
+DECL_TEMPLATE(linux,sys_setresuid);    // man page says "non-standard"
+DECL_TEMPLATE(linux,sys_getresuid);
+DECL_TEMPLATE(linux,sys_setresgid);    // man page says "non-standard"
+DECL_TEMPLATE(linux,sys_getresgid);
 
-LINUX_SYSCALL_WRAPPER(sys_ioperm);
-LINUX_SYSCALL_WRAPPER(sys_syslog);
-LINUX_SYSCALL_WRAPPER(sys_vhangup);
-LINUX_SYSCALL_WRAPPER(sys_sysinfo);
-LINUX_SYSCALL_WRAPPER(sys_personality);
-LINUX_SYSCALL_WRAPPER(sys_sysctl);
-LINUX_SYSCALL_WRAPPER(sys_prctl);
+DECL_TEMPLATE(linux,sys_ioperm);
+DECL_TEMPLATE(linux,sys_syslog);
+DECL_TEMPLATE(linux,sys_vhangup);
+DECL_TEMPLATE(linux,sys_sysinfo);
+DECL_TEMPLATE(linux,sys_personality);
+DECL_TEMPLATE(linux,sys_sysctl);
+DECL_TEMPLATE(linux,sys_prctl);
 
-LINUX_SYSCALL_WRAPPER(sys_sendfile);
-LINUX_SYSCALL_WRAPPER(sys_sendfile64);
-LINUX_SYSCALL_WRAPPER(sys_futex);
+DECL_TEMPLATE(linux,sys_sendfile);
+DECL_TEMPLATE(linux,sys_sendfile64);
+DECL_TEMPLATE(linux,sys_futex);
 
-LINUX_SYSCALL_WRAPPER(sys_epoll_create);
-LINUX_SYSCALL_WRAPPER(sys_epoll_ctl);
-LINUX_SYSCALL_WRAPPER(sys_epoll_wait);
+DECL_TEMPLATE(linux,sys_epoll_create);
+DECL_TEMPLATE(linux,sys_epoll_ctl);
+DECL_TEMPLATE(linux,sys_epoll_wait);
 
-LINUX_SYSCALL_WRAPPER(sys_gettid);
-LINUX_SYSCALL_WRAPPER(sys_tkill);
-LINUX_SYSCALL_WRAPPER(sys_tgkill);
+DECL_TEMPLATE(linux,sys_gettid);
+DECL_TEMPLATE(linux,sys_tkill);
+DECL_TEMPLATE(linux,sys_tgkill);
 
-LINUX_SYSCALL_WRAPPER(sys_fadvise64);
-LINUX_SYSCALL_WRAPPER(sys_fadvise64_64);
+DECL_TEMPLATE(linux,sys_fadvise64);
+DECL_TEMPLATE(linux,sys_fadvise64_64);
 
-LINUX_SYSCALL_WRAPPER(sys_io_setup);
-LINUX_SYSCALL_WRAPPER(sys_io_destroy);
-LINUX_SYSCALL_WRAPPER(sys_io_getevents);
-LINUX_SYSCALL_WRAPPER(sys_io_submit);
-LINUX_SYSCALL_WRAPPER(sys_io_cancel);
+DECL_TEMPLATE(linux,sys_io_setup);
+DECL_TEMPLATE(linux,sys_io_destroy);
+DECL_TEMPLATE(linux,sys_io_getevents);
+DECL_TEMPLATE(linux,sys_io_submit);
+DECL_TEMPLATE(linux,sys_io_cancel);
 
 #endif   // __PRIV_SYSCALLS_LINUX_H
 
diff --git a/coregrind/m_syscalls/priv_syscalls-main.h b/coregrind/m_syscalls/priv_syscalls-main.h
new file mode 100644
index 0000000..80823fd
--- /dev/null
+++ b/coregrind/m_syscalls/priv_syscalls-main.h
@@ -0,0 +1,43 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Private exports of syscalls-main.c.     priv_syscalls-main.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Nicholas Nethercote
+      njn@valgrind.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PRIV_SYSCALLS_MAIN_H
+#define __PRIV_SYSCALLS_MAIN_H
+
+/* Back up a thread so as to restart a system call. */
+extern
+void VG_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch );
+
+#endif   // __PRIV_SYSCALLS_MAIN_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                     priv_syscalls-main.h ---*/
+/*--------------------------------------------------------------------*/
+
diff --git a/coregrind/m_syscalls/priv_syscalls-x86-linux.h b/coregrind/m_syscalls/priv_syscalls-x86-linux.h
index 69218ce..1c6fc97 100644
--- a/coregrind/m_syscalls/priv_syscalls-x86-linux.h
+++ b/coregrind/m_syscalls/priv_syscalls-x86-linux.h
@@ -31,23 +31,6 @@
 #ifndef __PRIV_SYSCALLS_X86_LINUX_H
 #define __PRIV_SYSCALLS_X86_LINUX_H
 
-// Accessors for the ThreadArchState
-#define VGP_SYSCALL_NUM       guest_EAX
-#define VGP_SYSCALL_ARG1      guest_EBX
-#define VGP_SYSCALL_ARG2      guest_ECX
-#define VGP_SYSCALL_ARG3      guest_EDX
-#define VGP_SYSCALL_ARG4      guest_ESI
-#define VGP_SYSCALL_ARG5      guest_EDI
-#define VGP_SYSCALL_ARG6      guest_EBP
-#define VGP_SYSCALL_RET       guest_EAX
-
-// Setting a syscall result
-#define VGP_SET_SYSCALL_RESULT(regs, val)    ((regs).vex.guest_EAX = (val))
-
-// For informing tools that a syscall result has been set.
-#define VGP_TRACK_SYSCALL_RETVAL(zztid) \
-   VG_TRACK( post_reg_write, Vg_CoreSysCall, zztid, O_SYSCALL_RET, sizeof(UWord) );
-
 #endif   // __PRIV_SYSCALLS_X86_LINUX_H
 
 /*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syscalls/priv_syscalls.h b/coregrind/m_syscalls/priv_syscalls.h
deleted file mode 100644
index c60b579..0000000
--- a/coregrind/m_syscalls/priv_syscalls.h
+++ /dev/null
@@ -1,515 +0,0 @@
-/*--------------------------------------------------------------------*/
-/*--- Private syscalls header.                     priv_syscalls.h ---*/
-/*--------------------------------------------------------------------*/
-
-/*
-   This file is part of Valgrind, a dynamic binary instrumentation
-   framework.
-
-   Copyright (C) 2000-2005 Julian Seward
-      jseward@acm.org
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307, USA.
-
-   The GNU General Public License is contained in the file COPYING.
-*/
-
-#ifndef __PRIV_SYSCALLS_H
-#define __PRIV_SYSCALLS_H
-
-#include "pub_core_options.h"
-#include "pub_core_signals.h"
-
-#if defined(VGO_linux)
-#  include "priv_syscalls-linux.h"
-#else
-#  error Unknown OS
-#endif
-
-#if defined(VGP_amd64_linux)
-#  include "priv_syscalls-amd64-linux.h"
-#elif defined(VGP_arm_linux)
-#  include "priv_syscalls-arm-linux.h"
-#elif defined(VGP_x86_linux)
-#  include "priv_syscalls-x86-linux.h"
-#else
-#  error Unknown platform
-#endif
-
-#include "vki_unistd.h"
-
-// Offsets for the shadow state
-#define O_SYSCALL_NUM   (offsetof(VexGuestArchState, VGP_SYSCALL_NUM))
-#define O_SYSCALL_ARG1  (offsetof(VexGuestArchState, VGP_SYSCALL_ARG1))
-#define O_SYSCALL_ARG2  (offsetof(VexGuestArchState, VGP_SYSCALL_ARG2))
-#define O_SYSCALL_ARG3  (offsetof(VexGuestArchState, VGP_SYSCALL_ARG3))
-#define O_SYSCALL_ARG4  (offsetof(VexGuestArchState, VGP_SYSCALL_ARG4))
-#define O_SYSCALL_ARG5  (offsetof(VexGuestArchState, VGP_SYSCALL_ARG5))
-#define O_SYSCALL_ARG6  (offsetof(VexGuestArchState, VGP_SYSCALL_ARG6))
-#define O_SYSCALL_RET   (offsetof(VexGuestArchState, VGP_SYSCALL_RET))
-
-// The syscall table
-struct SyscallTableEntry {
-   UInt  *flags_ptr;
-   void (*before)(ThreadId tid, ThreadState *tst /*, UInt *flags*/);
-   void (*after) (ThreadId tid, ThreadState *tst);
-};
-
-/* This table is the mapping from __NR_xxx syscall numbers to the PRE/POST
-   wrappers for the relevant syscalls used in the OS kernel for that number.
-   Note that the constant names don't always match the wrapper names in a
-   straightforward way.  For example, on x86/Linux: 
-      
-      __NR_lchown       --> sys_lchown16()
-      __NR_lchown32     --> sys_lchown()
-      __NR_select       --> old_select()
-      __NR__newselect   --> sys_select()
-*/
-extern const struct SyscallTableEntry VGA_(syscall_table)[];
-
-extern const UInt VGA_(syscall_table_size);
-   
-extern Int VG_(clone) ( Int (*fn)(void *), void *stack, Int flags, void *arg, 
-			Int *child_tid, Int *parent_tid, vki_modify_ldt_t * );
-
-/*
-  Perform a syscall on behalf of a client thread, using a specific
-  signal mask.  On completion, the signal mask is set to restore_mask
-  (which presumably blocks almost everything).  If a signal happens
-  during the syscall, the handler should call
-  VGA_(interrupted_syscall)() to adjust the thread's context to do the
-  right thing.
-*/
-extern void VGA_(client_syscall)(Int syscallno, ThreadState *tst,
-				 const vki_sigset_t *syscall_mask);
-
-/* Simple Valgrind-internal atfork mechanism */
-extern void VG_(do_atfork_pre)   (ThreadId tid);
-extern void VG_(do_atfork_parent)(ThreadId tid);
-extern void VG_(do_atfork_child) (ThreadId tid);
-
-// Return true if address range entirely contained within client
-// address space.
-Bool VG_(valid_client_addr)(Addr start, SizeT size, ThreadId tid,
-                            const Char *syscallname);
-
-// Return true if we're allowed to use or create this fd.
-Bool VG_(fd_allowed)(Int fd, const Char *syscallname, ThreadId tid, Bool soft);
-
-void VG_(record_fd_open)(ThreadId tid, Int fd, char *pathname);
-
-// Used when killing threads -- we must not kill a thread if it's the thread
-// that would do Valgrind's final cleanup and output.
-Bool VG_(do_sigkill)(Int pid, Int tgid);
-   
-// Flags describing syscall wrappers
-#define Special    (1 << 0)	/* handled specially			*/
-#define MayBlock   (1 << 1)	/* may block				*/
-#define PostOnFail (1 << 2)	/* call POST() function on failure	*/
-#define PadAddr	   (1 << 3)	/* pad+unpad address space around syscall */
-#define Done       (1 << 4)	/* used if a PRE() did the syscall	*/
-
-// Templates for generating the PRE and POST macros.  For ones that must be
-// publically visible, use an empty 'qual', 'prefix' should start with
-// "vgArch_" or similar, and there should be corresponding global
-// declarations (like the GEN_SYSCALL_WRAPPER ones below).  Otherwise, use
-// "static" for 'qual', and "vgArch_" should not be in the 'prefix'.
-#define PRE_TEMPLATE(qual, prefix, name, f) \
-   qual UInt prefix##_##name##_flags = f; \
-   qual void prefix##_##name##_before(ThreadId tid, ThreadState *tst)
-#define POST_TEMPLATE(qual, prefix, name) \
-   qual void prefix##_##name##_after (ThreadId tid, ThreadState *tst)
-
-// This macro is used to write other macros which making writing syscall
-// tables easier.
-#define SYS_WRAPPER_ENTRY_X_(prefix, const, name) \
-   [const] = { &prefix##_##name##_flags, \
-                prefix##_##name##_before, NULL }
-#define SYS_WRAPPER_ENTRY_XY(prefix, const, name) \
-   [const] = { &prefix##_##name##_flags, \
-                prefix##_##name##_before, \
-                prefix##_##name##_after }
-
-// Macros for adding generic wrappers to a syscall table.
-#define GENX_(const, name)    SYS_WRAPPER_ENTRY_X_(vgArch_gen, const, name)
-#define GENXY(const, name)    SYS_WRAPPER_ENTRY_XY(vgArch_gen, const, name)
-
-// Space-saving macros for syscall PRE() and POST() wrappers
-#define RES    ((tst->arch).vex.VGP_SYSCALL_RET)
-#define SYSNO  ((tst->arch).vex.VGP_SYSCALL_NUM)
-#define ARG1   ((tst->arch).vex.VGP_SYSCALL_ARG1)
-#define ARG2   ((tst->arch).vex.VGP_SYSCALL_ARG2)
-#define ARG3   ((tst->arch).vex.VGP_SYSCALL_ARG3)
-#define ARG4   ((tst->arch).vex.VGP_SYSCALL_ARG4)
-#define ARG5   ((tst->arch).vex.VGP_SYSCALL_ARG5)
-#define ARG6   ((tst->arch).vex.VGP_SYSCALL_ARG6)
-
-// For setting the result of a syscall in a wrapper
-#define SET_RESULT(val)                            \
-   do { VGP_SET_SYSCALL_RESULT(tst->arch, (val));  \
-        tst->syscall_result_set = True;            \
-   } while (0)
-
-#define PRINT(format, args...)  \
-   if (VG_(clo_trace_syscalls))        \
-      VG_(printf)(format, ## args)
-
-// Generic (platform-independent) syscall wrappers.  These are generally
-// POSIX or something like that;  those that are not POSIX are annotated
-// with what standards they are part of, as stated in the Linux man pages.
-// For many of them, it's unclear if they are generic, or Linux-specific, or
-// x86/Linux-specific, or something else again.
-//
-// Nb: This list may change over time... ones thought at first to be generic
-// may turn out not to be, and so be moved into OS-specific or
-// platform-specific files.  If there's any doubt, I'm leaving them in here.
-//
-// Nb 2: if porting to a new OS, you should really check all these generic
-// wrappers to make sure they match your OS, painful as it might be.
-//
-// For each generic ("gen") wrapper, we declare the pre-wrapper, the
-// post-wrapper (which is actually not always needed), and the associated
-// flags.
-#define GEN_SYSCALL_WRAPPER(x) \
-   extern UInt VGA_(gen_##x##_flags); \
-   extern void VGA_(gen_##x##_before)(ThreadId tid, ThreadState *tst); \
-   extern void VGA_(gen_##x##_after) (ThreadId tid, ThreadState *tst)
-
-GEN_SYSCALL_WRAPPER(sys_ni_syscall);            // * P -- unimplemented
-GEN_SYSCALL_WRAPPER(sys_exit);
-GEN_SYSCALL_WRAPPER(sys_fork);
-GEN_SYSCALL_WRAPPER(sys_read);
-GEN_SYSCALL_WRAPPER(sys_write);
-GEN_SYSCALL_WRAPPER(sys_open);
-GEN_SYSCALL_WRAPPER(sys_close);
-GEN_SYSCALL_WRAPPER(sys_waitpid);
-GEN_SYSCALL_WRAPPER(sys_creat);
-GEN_SYSCALL_WRAPPER(sys_link);
-GEN_SYSCALL_WRAPPER(sys_unlink);
-GEN_SYSCALL_WRAPPER(sys_execve);    // (*??) P
-GEN_SYSCALL_WRAPPER(sys_chdir);
-GEN_SYSCALL_WRAPPER(sys_time);
-GEN_SYSCALL_WRAPPER(sys_mknod);
-GEN_SYSCALL_WRAPPER(sys_chmod);
-GEN_SYSCALL_WRAPPER(sys_lseek);
-GEN_SYSCALL_WRAPPER(sys_getpid);
-GEN_SYSCALL_WRAPPER(sys_alarm);
-GEN_SYSCALL_WRAPPER(sys_pause);
-GEN_SYSCALL_WRAPPER(sys_utime);
-GEN_SYSCALL_WRAPPER(sys_access);
-GEN_SYSCALL_WRAPPER(sys_kill);
-GEN_SYSCALL_WRAPPER(sys_rename);
-GEN_SYSCALL_WRAPPER(sys_mkdir);
-GEN_SYSCALL_WRAPPER(sys_rmdir);
-GEN_SYSCALL_WRAPPER(sys_dup);
-GEN_SYSCALL_WRAPPER(sys_times);
-GEN_SYSCALL_WRAPPER(sys_fcntl);        // POSIX (but complicated)
-GEN_SYSCALL_WRAPPER(sys_setpgid);
-GEN_SYSCALL_WRAPPER(sys_umask);
-GEN_SYSCALL_WRAPPER(sys_dup2);
-GEN_SYSCALL_WRAPPER(sys_getppid);
-GEN_SYSCALL_WRAPPER(sys_getpgrp);
-GEN_SYSCALL_WRAPPER(sys_setsid);
-GEN_SYSCALL_WRAPPER(sys_munmap);
-GEN_SYSCALL_WRAPPER(sys_truncate);
-GEN_SYSCALL_WRAPPER(sys_ftruncate);
-GEN_SYSCALL_WRAPPER(sys_fchmod);
-GEN_SYSCALL_WRAPPER(sys_msync);
-GEN_SYSCALL_WRAPPER(sys_readv);
-GEN_SYSCALL_WRAPPER(sys_writev);
-GEN_SYSCALL_WRAPPER(sys_getsid);
-GEN_SYSCALL_WRAPPER(sys_fdatasync);
-GEN_SYSCALL_WRAPPER(sys_mlock);
-GEN_SYSCALL_WRAPPER(sys_munlock);
-GEN_SYSCALL_WRAPPER(sys_mlockall);
-GEN_SYSCALL_WRAPPER(sys_munlockall);
-GEN_SYSCALL_WRAPPER(sys_sched_setparam);
-GEN_SYSCALL_WRAPPER(sys_sched_getparam);
-GEN_SYSCALL_WRAPPER(sys_sched_rr_get_interval);
-GEN_SYSCALL_WRAPPER(sys_sched_setscheduler);
-GEN_SYSCALL_WRAPPER(sys_sched_getscheduler);
-GEN_SYSCALL_WRAPPER(sys_sched_yield);
-GEN_SYSCALL_WRAPPER(sys_sched_get_priority_max);
-GEN_SYSCALL_WRAPPER(sys_sched_get_priority_min);
-GEN_SYSCALL_WRAPPER(sys_nanosleep);
-GEN_SYSCALL_WRAPPER(sys_mremap);    // POSIX, but Linux arg order may be odd
-GEN_SYSCALL_WRAPPER(sys_getuid);
-GEN_SYSCALL_WRAPPER(sys_getgid);
-GEN_SYSCALL_WRAPPER(sys_geteuid);
-GEN_SYSCALL_WRAPPER(sys_getegid);
-GEN_SYSCALL_WRAPPER(sys_getpgid);
-GEN_SYSCALL_WRAPPER(sys_fsync);
-GEN_SYSCALL_WRAPPER(sys_wait4);
-GEN_SYSCALL_WRAPPER(sys_mprotect);
-GEN_SYSCALL_WRAPPER(sys_sigprocmask);
-GEN_SYSCALL_WRAPPER(sys_timer_create);    // Linux: varies across archs?
-GEN_SYSCALL_WRAPPER(sys_timer_settime);
-GEN_SYSCALL_WRAPPER(sys_timer_gettime);
-GEN_SYSCALL_WRAPPER(sys_timer_getoverrun);
-GEN_SYSCALL_WRAPPER(sys_timer_delete);
-GEN_SYSCALL_WRAPPER(sys_clock_settime);
-GEN_SYSCALL_WRAPPER(sys_clock_gettime);
-GEN_SYSCALL_WRAPPER(sys_clock_getres);
-GEN_SYSCALL_WRAPPER(sys_clock_nanosleep);
-GEN_SYSCALL_WRAPPER(sys_getcwd);
-GEN_SYSCALL_WRAPPER(sys_symlink);
-GEN_SYSCALL_WRAPPER(sys_getgroups);
-GEN_SYSCALL_WRAPPER(sys_setgroups);             // SVr4, SVID, X/OPEN, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_chown);
-GEN_SYSCALL_WRAPPER(sys_setuid);
-GEN_SYSCALL_WRAPPER(sys_gettimeofday);
-GEN_SYSCALL_WRAPPER(sys_madvise);
-GEN_SYSCALL_WRAPPER(sys_sigpending);
-
-// These ones aren't POSIX, but are in some standard and look reasonably
-// generic, and are the same for all architectures under Linux.
-GEN_SYSCALL_WRAPPER(sys_nice);      // SVr4, SVID EXT, AT&T, X/OPEN, BSD 4.3
-GEN_SYSCALL_WRAPPER(sys_sync);      // SVr4, SVID, X/OPEN, BSD 4.3
-GEN_SYSCALL_WRAPPER(sys_brk);       // 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_acct);      // SVR4, non-POSIX
-GEN_SYSCALL_WRAPPER(sys_chroot);    // SVr4, SVID, 4.4BSD, X/OPEN
-GEN_SYSCALL_WRAPPER(sys_readlink);  // X/OPEN, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_fchdir);    // SVr4, SVID, POSIX, X/OPEN, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_getdents);  // SVr4,SVID
-GEN_SYSCALL_WRAPPER(sys_select);    // 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_flock);     // 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_poll);      // XPG4-UNIX
-GEN_SYSCALL_WRAPPER(sys_getrusage); // SVr4, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_stime);	    // SVr4, SVID, X/OPEN
-GEN_SYSCALL_WRAPPER(sys_settimeofday); // SVr4, 4.3BSD (non-POSIX)
-GEN_SYSCALL_WRAPPER(sys_getpriority);  // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_setpriority);  // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_setitimer);    // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_getitimer);    // SVr4, 4.4BSD
-GEN_SYSCALL_WRAPPER(sys_setreuid);     // 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_setregid);     // 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_fchown);       // SVr4,4.3BSD
-GEN_SYSCALL_WRAPPER(sys_setgid);       // SVr4,SVID
-GEN_SYSCALL_WRAPPER(sys_utimes);       // 4.3BSD
-
-// These ones may be Linux specific... not sure.  They use 16-bit gid_t and
-// uid_t types.  The similarly named (minus the "16" suffix) ones below use
-// 32-bit versions of these types.
-GEN_SYSCALL_WRAPPER(sys_setuid16);              // ## P
-GEN_SYSCALL_WRAPPER(sys_getuid16);              // ## P
-GEN_SYSCALL_WRAPPER(sys_setgid16);              // ## SVr4,SVID
-GEN_SYSCALL_WRAPPER(sys_getgid16);              // ## P
-GEN_SYSCALL_WRAPPER(sys_geteuid16);             // ## P
-GEN_SYSCALL_WRAPPER(sys_getegid16);             // ## P
-GEN_SYSCALL_WRAPPER(sys_setreuid16);            // ## BSD4.3
-GEN_SYSCALL_WRAPPER(sys_setregid16);            // ## BSD4.3
-GEN_SYSCALL_WRAPPER(sys_getgroups16);           // ## P
-GEN_SYSCALL_WRAPPER(sys_setgroups16);           // ## SVr4, SVID, X/OPEN, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_fchown16);              // ## SVr4,BSD4.3
-GEN_SYSCALL_WRAPPER(sys_chown16);               // ## P
-
-// Linux's funny many-in-one socketcall is certainly not generic, but I
-// didn't want to move it until necessary because it's big and has a lot of
-// associated junk.
-GEN_SYSCALL_WRAPPER(sys_socketcall);
-
-// Some archs on Linux do not match the generic wrapper for sys_pipe().
-GEN_SYSCALL_WRAPPER(sys_pipe);
-
-// May not be generic for every architecture under Linux.
-GEN_SYSCALL_WRAPPER(sys_sigaction);             // (x86) P
-
-// Funny names, not sure...
-GEN_SYSCALL_WRAPPER(sys_newstat);               // * P
-GEN_SYSCALL_WRAPPER(sys_newlstat);              // *
-GEN_SYSCALL_WRAPPER(sys_newfstat);              // * P (SVr4,BSD4.3)
-
-// For the remainder, not really sure yet
-GEN_SYSCALL_WRAPPER(old_mmap);                  // x86, weird arg passing
-GEN_SYSCALL_WRAPPER(sys_ptrace);                // (x86?) (almost-P)
-GEN_SYSCALL_WRAPPER(sys_sigsuspend);            // POSIX, but L (proto varies across archs)
-GEN_SYSCALL_WRAPPER(sys_setrlimit);             // SVr4, 4.3BSD
-GEN_SYSCALL_WRAPPER(sys_ioctl);                 // x86? (various)
-GEN_SYSCALL_WRAPPER(sys_old_getrlimit);         // SVr4, 4.3BSD L?
-GEN_SYSCALL_WRAPPER(sys_statfs);                // * L?
-GEN_SYSCALL_WRAPPER(sys_fstatfs);               // * L?
-GEN_SYSCALL_WRAPPER(sys_iopl);                  // (x86/amd64) L
-GEN_SYSCALL_WRAPPER(sys_ipc);                   // (x86) L
-GEN_SYSCALL_WRAPPER(sys_newuname);              // * P
-GEN_SYSCALL_WRAPPER(sys_init_module);           // * L?
-GEN_SYSCALL_WRAPPER(sys_quotactl);              // * (?)
-GEN_SYSCALL_WRAPPER(sys_rt_sigaction);          // (x86) ()
-GEN_SYSCALL_WRAPPER(sys_rt_sigprocmask);        // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigpending);         // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigtimedwait);       // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigqueueinfo);       // * ?
-GEN_SYSCALL_WRAPPER(sys_rt_sigsuspend);         // () ()
-GEN_SYSCALL_WRAPPER(sys_pread64);               // * (Unix98?)
-GEN_SYSCALL_WRAPPER(sys_pwrite64);              // * (Unix98?)
-GEN_SYSCALL_WRAPPER(sys_capget);                // * L?
-GEN_SYSCALL_WRAPPER(sys_capset);                // * L?
-GEN_SYSCALL_WRAPPER(sys_sigaltstack);           // (x86) (XPG4-UNIX)
-GEN_SYSCALL_WRAPPER(sys_getpmsg);               // (?) (?)
-GEN_SYSCALL_WRAPPER(sys_putpmsg);               // (?) (?)
-GEN_SYSCALL_WRAPPER(sys_getrlimit);             // * (?)
-GEN_SYSCALL_WRAPPER(sys_mmap2);                 // (x86?) P?
-GEN_SYSCALL_WRAPPER(sys_truncate64);            // %% (P?)
-GEN_SYSCALL_WRAPPER(sys_ftruncate64);           // %% (P?)
-GEN_SYSCALL_WRAPPER(sys_stat64);                // %% (?)
-GEN_SYSCALL_WRAPPER(sys_lstat64);               // %% (?)
-GEN_SYSCALL_WRAPPER(sys_fstat64);               // %% (?)
-GEN_SYSCALL_WRAPPER(sys_lchown);                // * (L?)
-GEN_SYSCALL_WRAPPER(sys_mincore);               // * L?
-GEN_SYSCALL_WRAPPER(sys_getdents64);            // * (SVr4,SVID?)
-GEN_SYSCALL_WRAPPER(sys_fcntl64);               // * P?
-GEN_SYSCALL_WRAPPER(sys_setxattr);              // * L?
-GEN_SYSCALL_WRAPPER(sys_lsetxattr);             // * L?
-GEN_SYSCALL_WRAPPER(sys_fsetxattr);             // * L?
-GEN_SYSCALL_WRAPPER(sys_getxattr);              // * L?
-GEN_SYSCALL_WRAPPER(sys_lgetxattr);             // * L?
-GEN_SYSCALL_WRAPPER(sys_fgetxattr);             // * L?
-GEN_SYSCALL_WRAPPER(sys_listxattr);             // * L?
-GEN_SYSCALL_WRAPPER(sys_llistxattr);            // * L?
-GEN_SYSCALL_WRAPPER(sys_flistxattr);            // * L?
-GEN_SYSCALL_WRAPPER(sys_removexattr);           // * L?
-GEN_SYSCALL_WRAPPER(sys_lremovexattr);          // * L?
-GEN_SYSCALL_WRAPPER(sys_fremovexattr);          // * L?
-GEN_SYSCALL_WRAPPER(sys_sched_setaffinity);     // * L?
-GEN_SYSCALL_WRAPPER(sys_sched_getaffinity);     // * L?
-GEN_SYSCALL_WRAPPER(sys_lookup_dcookie);        // (*/32/64) L
-GEN_SYSCALL_WRAPPER(sys_set_tid_address);       // * ?
-GEN_SYSCALL_WRAPPER(sys_statfs64);              // * (?)
-GEN_SYSCALL_WRAPPER(sys_fstatfs64);             // * (?)
-GEN_SYSCALL_WRAPPER(sys_mq_open);               // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_unlink);             // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_timedsend);          // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_timedreceive);       // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_notify);             // * P?
-GEN_SYSCALL_WRAPPER(sys_mq_getsetattr);         // * P?
-
-#undef GEN_SYSCALL_WRAPPER
-
-// Macros used in syscall wrappers
-/* PRRAn == "pre-register-read-argument"
-   PRRSN == "pre-register-read-syscall"
-*/
-
-#define PRRSN \
-      VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
-                                    O_SYSCALL_NUM, sizeof(UWord));
-#define PRRAn(n,s,t,a) \
-      VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, s"("#a")", \
-                                    O_SYSCALL_ARG##n, sizeof(t));
-#define PRE_REG_READ0(tr, s) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-   }
-#define PRE_REG_READ1(tr, s, t1, a1) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-      PRRAn(1,s,t1,a1); \
-   }
-#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); \
-   }
-#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
-   }
-#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
-      PRRAn(4,s,t4,a4); \
-   }
-#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
-      PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); \
-   }
-#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
-   if (VG_(tdict).track_pre_reg_read) { \
-      PRRSN; \
-      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
-      PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); PRRAn(6,s,t6,a6); \
-   }
-
-#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
-   VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
-
-#define PRE_MEM_RASCIIZ(zzname, zzaddr) \
-   VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
-
-#define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
-   VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
-
-#define POST_MEM_WRITE(zzaddr, zzlen) \
-   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
-
-
-//////////////////////////////////////////////////////////
-
-#define TId ThreadId
-#define UW  UWord
-
-extern void  VG_(generic_PRE_sys_socketpair)   ( TId, UW, UW, UW, UW );
-extern UWord VG_(generic_POST_sys_socketpair)  ( TId, UW, UW, UW, UW, UW );
-extern UWord VG_(generic_POST_sys_socket)      ( TId, UW );
-extern void  VG_(generic_PRE_sys_bind)         ( TId, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_accept)       ( TId, UW, UW, UW );
-extern UWord VG_(generic_POST_sys_accept)      ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_sendto)       ( TId, UW, UW, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_send)         ( TId, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_recvfrom)     ( TId, UW, UW, UW, UW, UW, UW );
-extern void  VG_(generic_POST_sys_recvfrom)    ( TId, UW, UW, UW, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_recv)         ( TId, UW, UW, UW );
-extern void  VG_(generic_POST_sys_recv)        ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_connect)      ( TId, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_setsockopt)   ( TId, UW, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_getsockopt)   ( TId, UW, UW, UW, UW, UW );
-extern void  VG_(generic_POST_sys_getsockopt)  ( TId, UW, UW, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_getsockname)  ( TId, UW, UW, UW );
-extern void  VG_(generic_POST_sys_getsockname) ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_getpeername)  ( TId, UW, UW, UW );
-extern void  VG_(generic_POST_sys_getpeername) ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_sendmsg)      ( TId, UW, UW );
-extern void  VG_(generic_PRE_sys_recvmsg)      ( TId, UW, UW );
-extern void  VG_(generic_POST_sys_recvmsg)     ( TId, UW, UW, UW );
-
-extern void  VG_(generic_PRE_sys_semop)        ( TId, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_semtimedop)   ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_semctl)       ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_POST_sys_semctl)      ( TId, UW, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_msgsnd)       ( TId, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_msgrcv)       ( TId, UW, UW, UW, UW, UW );
-extern void  VG_(generic_POST_sys_msgrcv)      ( TId, UW, UW, UW, UW, UW, UW );
-extern void  VG_(generic_PRE_sys_msgctl)       ( TId, UW, UW, UW );
-extern void  VG_(generic_POST_sys_msgctl)      ( TId, UW, UW, UW, UW );
-extern UWord VG_(generic_PRE_sys_shmat)        ( TId, UW, UW, UW );
-extern void  VG_(generic_POST_sys_shmat)       ( TId, UW, UW, UW, UW );
-extern Bool  VG_(generic_PRE_sys_shmdt)        ( TId, UW );
-extern void  VG_(generic_POST_sys_shmdt)       ( TId, UW, UW );
-extern void  VG_(generic_PRE_sys_shmctl)       ( TId, UW, UW, UW );
-extern void  VG_(generic_POST_sys_shmctl)      ( TId, UW, UW, UW, UW );
-
-#undef TId
-#undef UW
-
-#endif   // __PRIV_SYSCALLS_H
-
-/*--------------------------------------------------------------------*/
-/*--- end                                                          ---*/
-/*--------------------------------------------------------------------*/
-
diff --git a/coregrind/m_syscalls/priv_types_n_macros.h b/coregrind/m_syscalls/priv_types_n_macros.h
new file mode 100644
index 0000000..711f061
--- /dev/null
+++ b/coregrind/m_syscalls/priv_types_n_macros.h
@@ -0,0 +1,348 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Types and macros for writing syscall wrappers.               ---*/
+/*---                                              priv_syscalls.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PRIV_TYPES_N_MACROS_H
+#define __PRIV_TYPES_N_MACROS_H
+
+/* requires #include "pub_core_options.h" */
+/* requires #include "pub_core_signals.h" */
+
+/* This header defines types and macros which are useful for writing
+   syscall wrappers.  It does not give prototypes for any such
+   headers, though: that is the job of the priv_syscalls-*.h headers.
+   This header gets included in any file which defines or declares
+   wrappers, and as such should only contain stuff which is relevant
+   to all such files.
+*/
+
+/* ---------------------------------------------------------------------
+   Types that are used in syscall wrappers.
+   ------------------------------------------------------------------ */
+
+/* Arguments for a syscall. */
+typedef
+   struct {
+      UWord sysno;
+      UWord arg1;
+      UWord arg2;
+      UWord arg3;
+      UWord arg4;
+      UWord arg5;
+      UWord arg6;
+   }
+   SyscallArgs;
+
+/* Current status of a syscall being done on behalf of the client. */
+typedef
+   struct {
+      enum { SsSuccess=1, SsFailure, SsHandToKernel, SsIdle } what;
+      UWord val; /* only meaningful for .what == Success or Failure */
+   }
+   SyscallStatus;
+
+/* Guest state layout info for syscall args. */
+typedef
+   struct {
+      Int o_sysno;
+      Int o_arg1;
+      Int o_arg2;
+      Int o_arg3;
+      Int o_arg4;
+      Int o_arg5;
+      Int o_arg6;
+      Int o_retval;
+   }
+   SyscallArgLayout;
+
+/* Flags describing syscall wrappers */
+#define SfMayBlock   (1 << 1)    /* may block                              */
+#define SfPostOnFail (1 << 2)    /* call POST() function on failure        */
+/* #define SfPadAddr (1 << 3) */ /* pad+unpad address space around syscall */
+#define SfPollAfter  (1 << 4)    /* poll for signals on completion         */
+#define SfYieldAfter (1 << 5)    /* yield on completion                    */
+
+
+/* ---------------------------------------------------------------------
+   The syscall table.
+   ------------------------------------------------------------------ */
+
+typedef
+   struct {
+      void (*before) ( ThreadId,
+                       SyscallArgLayout*,
+                       /*MOD*/SyscallArgs*,
+                       /*OUT*/SyscallStatus*,
+                       /*OUT*/UWord*
+                     );
+
+      void (*after)  ( ThreadId, 
+                       SyscallArgs*,
+                       SyscallStatus*
+                     );
+   }
+   SyscallTableEntry;
+
+/* Syscall table entries bind __NR_xxx syscall numbers to the PRE/POST
+   wrappers for the relevant syscall used in the OS kernel for that
+   number.  Note that the constant names don't always match the
+   wrapper names in a straightforward way.  For example, on x86/Linux:
+      
+      __NR_lchown       --> sys_lchown16()
+      __NR_lchown32     --> sys_lchown()
+      __NR_select       --> old_select()
+      __NR__newselect   --> sys_select()
+*/
+
+
+/* These are defined in the relevant platform-specific files --
+   syscalls-arch-os.c */
+
+extern const SyscallTableEntry VGP_(syscall_table)[];
+
+extern const UInt VGP_(syscall_table_size);
+   
+
+/* ---------------------------------------------------------------------
+   Declaring and defining wrappers.
+   ------------------------------------------------------------------ */
+
+/* Templates for generating the PRE and POST macros -- that is, the
+   formal parameter lists for the definitions of wrapper functions.
+
+   Since these names exist in the global namespace, 'auxstr' should
+   give an auxiliary string, eg, "generic", "x86_linux", "linux", etc,
+   that ensures the names won't clash with other wrappers.
+
+   You should create corresponding global declarations using
+   DECL_TEMPLATE (indirectly) below.  
+*/
+
+#define DEFN_PRE_TEMPLATE(auxstr, name)                          \
+   void vgSysWrap_##auxstr##_##name##_before                     \
+                                 ( ThreadId tid,                 \
+                                   SyscallArgLayout* layout,     \
+                                   /*MOD*/SyscallArgs* args,     \
+                                   /*OUT*/SyscallStatus* status, \
+                                   /*OUT*/UWord* flags           \
+                                 )
+
+#define DEFN_POST_TEMPLATE(auxstr, name)                         \
+   void vgSysWrap_##auxstr##_##name##_after                      \
+                                 ( ThreadId tid,                 \
+                                   SyscallArgs* args,            \
+                                   SyscallStatus* status         \
+                                 )
+
+
+/* This macro generates declarations (prototypes) for wrappers.  It
+   declares both the pre-wrapper and the post-wrapper, even though the
+   post-wrapper may not actually exist.
+*/
+#define DECL_TEMPLATE(auxstr, name)                              \
+   extern                                                        \
+   void vgSysWrap_##auxstr##_##name##_before                     \
+                                 ( ThreadId tid,                 \
+                                   SyscallArgLayout* layout,     \
+                                   /*MOD*/SyscallArgs* args,     \
+                                   /*OUT*/SyscallStatus* status, \
+                                   /*OUT*/UWord* flags           \
+                                 );                              \
+   extern                                                        \
+   void vgSysWrap_##auxstr##_##name##_after                      \
+                                 ( ThreadId tid,                 \
+                                   SyscallArgs* args,            \
+                                   SyscallStatus* status         \
+                                 );
+
+
+
+/* Macros for conveniently generating entries in the syscall
+   tables.  This first pair are not used directly. */
+
+#define WRAPPER_ENTRY_X_(auxstr, sysno, name) \
+   [sysno] = { vgSysWrap_##auxstr##_##name##_before, NULL }
+#define WRAPPER_ENTRY_XY(auxstr, sysno, name) \
+   [sysno] = { vgSysWrap_##auxstr##_##name##_before, \
+               vgSysWrap_##auxstr##_##name##_after }
+
+/* Add a generic wrapper to a syscall table. */
+#define GENX_(sysno, name)    WRAPPER_ENTRY_X_(generic, sysno, name)
+#define GENXY(sysno, name)    WRAPPER_ENTRY_XY(generic, sysno, name)
+
+/* Add a Linux-specific, arch-independent wrapper to a syscall
+   table. */
+#define LINX_(sysno, name)    WRAPPER_ENTRY_X_(linux, sysno, name) 
+#define LINXY(sysno, name)    WRAPPER_ENTRY_XY(linux, sysno, name)
+
+
+
+/* ---------------------------------------------------------------------
+   Macros useful for writing wrappers concisely.  These refer to the
+   parameters declared by DEFN_{PRE,POST}_TEMPLATE and so in a way do
+   not help clarity of understanding.  But they are just too useful to
+   omit.
+   ------------------------------------------------------------------ */
+
+/* Reference to the syscall's arguments -- the ones which the
+   pre-wrapper may have modified, not the original copy. */
+#define SYSNO  (args->sysno)
+#define ARG1   (args->arg1)
+#define ARG2   (args->arg2)
+#define ARG3   (args->arg3)
+#define ARG4   (args->arg4)
+#define ARG5   (args->arg5)
+#define ARG6   (args->arg6)
+
+/* Reference to the syscall's current result status/value.  Note that
+   
+   (1) status->val by itself is meaningless -- you have to consider it
+       together with status->what, which is why RES uses a helper
+       function (this also has the desirable effect of turning RES
+       into a non-lvalue).
+
+   (2) post-wrappers will not get called in case of failure (unless
+       PostOnFail is set, which is rare).  This is why the assertion
+       in getRES is viable.
+
+   If you really really want to just get hold of status->val without
+   inspecting status->what, use RES_unchecked.  This is dangerous and
+   therefore discouraged.  
+*/
+#define SUCCESS       (status->what == SsSuccess)
+#define FAILURE       (status->what == SsFailure)
+#define SWHAT         (status->what)
+#define RES_unchecked (status->val)     /* do not use! */
+#define RES           (getRES(status))  /* use this instead, if possible */
+
+static inline UWord getRES ( SyscallStatus* st ) {
+   vg_assert(st->what == SsSuccess);
+   return st->val;
+}
+
+
+/* Set the current result status/value in various ways. */
+#define SET_STATUS_Success(zzz)                      \
+   do { status->what = SsSuccess;                    \
+        status->val  = (zzz);                        \
+   } while (0)
+
+#define SET_STATUS_Failure(zzz)                      \
+   do { Word wzz = (Word)(zzz);                      \
+        /* Catch out wildly bogus error values. */   \
+        vg_assert(wzz >= 0 && wzz < 10000);          \
+        status->what = SsFailure;                    \
+        status->val  = wzz;                          \
+   } while (0)
+
+#define SET_STATUS_from_SysRes(zzz)                  \
+   do {                                              \
+      SysRes zres = (zzz);                           \
+      if (zres.isError) {                            \
+         SET_STATUS_Failure(zres.val);               \
+      } else {                                       \
+         SET_STATUS_Success(zres.val);               \
+      }                                              \
+   } while (0)
+
+#define PRINT(format, args...)                       \
+   if (VG_(clo_trace_syscalls))                      \
+      VG_(printf)(format, ## args)
+
+
+/* Macros used to tell tools about uses of scalar arguments.  Note,
+   these assume little-endianness.  These can only be used in
+   pre-wrappers, and they refer to the layout parameter passed in. */
+/* PRRAn == "pre-register-read-argument"
+   PRRSN == "pre-register-read-syscall"
+*/
+
+#define PRRSN \
+      VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
+                                    layout->o_sysno, sizeof(UWord));
+#define PRRAn(n,s,t,a) \
+      VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, s"("#a")", \
+                                    layout->o_arg##n, sizeof(t));
+#define PRE_REG_READ0(tr, s) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+   }
+#define PRE_REG_READ1(tr, s, t1, a1) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+      PRRAn(1,s,t1,a1); \
+   }
+#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); \
+   }
+#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+   }
+#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+      PRRAn(4,s,t4,a4); \
+   }
+#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+      PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); \
+   }
+#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
+   if (VG_(tdict).track_pre_reg_read) { \
+      PRRSN; \
+      PRRAn(1,s,t1,a1); PRRAn(2,s,t2,a2); PRRAn(3,s,t3,a3); \
+      PRRAn(4,s,t4,a4); PRRAn(5,s,t5,a5); PRRAn(6,s,t6,a6); \
+   }
+
+#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
+   VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
+
+#define PRE_MEM_RASCIIZ(zzname, zzaddr) \
+   VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
+
+#define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
+   VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
+
+#define POST_MEM_WRITE(zzaddr, zzlen) \
+   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
+
+
+#endif   // __PRIV_TYPES_N_MACROS_H
+
+/*--------------------------------------------------------------------*/
+/*--- end                                    priv_types_n_macros.h ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syscalls/syscall-x86-linux.S b/coregrind/m_syscalls/syscall-x86-linux.S
index ea45472..5e403b0 100644
--- a/coregrind/m_syscalls/syscall-x86-linux.S
+++ b/coregrind/m_syscalls/syscall-x86-linux.S
@@ -32,104 +32,6 @@
 #include "vki_unistd.h"
 #include "libvex_guest_offsets.h"
 		
-.globl	VG_(do_syscall)
-
-/*
-	Perform a Linux syscall with int 0x80
-	
-	Syscall args are passed on the stack
-	Int VG_(do_syscall)(Int syscall_no, UWord a1, UWord a2, UWord a3,
-					    UWord a4, UWord a5, UWord a6)
-
-	This has no effect on the virtual machine; the assumption is
-	that the syscall mechanism makes no useful changes to any
-	register except %eax, which is returned. (Some kernels will
-	change other registers randomly, but they're just compiler
-	spill values.)
- */
-VG_(do_syscall):
-	push	%esi
-	push	%edi
-	push	%ebx
-	push	%ebp
-	movl	16+ 4(%esp),%eax
-	movl	16+ 8(%esp),%ebx
-	movl	16+12(%esp),%ecx
-	movl	16+16(%esp),%edx
-	movl	16+20(%esp),%esi
-	movl	16+24(%esp),%edi
-	movl	16+28(%esp),%ebp
-	int	$0x80
-	popl	%ebp
-	popl	%ebx
-	popl	%edi
-	popl	%esi
-	ret
-
-/*
-	Perform a clone system call.  clone is strange because it has
-	fork()-like return-twice semantics, so it needs special
-	handling here.
-
-	Upon entry, we have:
-
-	    int (fn)(void*)	in  0+FSZ(%esp)
-	    void* child_stack   in  4+FSZ(%esp)
-	    int flags           in  8+FSZ(%esp)
-	    void* arg           in 12+FSZ(%esp)
-	    pid_t* child_tid    in 16+FSZ(%esp)
-	    pid_t* parent_tid   in 20+FSZ(%esp)
-	    void* tls_ptr       in 24+FSZ(%esp)
-
-	System call requires:
-
-	    int    $__NR_clone  in %eax
-	    int    flags	in %ebx
-	    void*  child_stack	in %ecx
-	    pid_t* parent_tid	in %edx
-	    pid_t* child_tid	in %edi
-	    void*  tls_ptr      in %esi
- */
-.globl VG_(clone)
-VG_(clone):
-#define FSZ	(4+4+4)			/* frame size = retaddr+ebx+edi */
-	push	%ebx
-	push	%edi
-	/* set up child stack with function and arg */
-	movl	 4+FSZ(%esp), %ecx	/* syscall arg2: child stack */
-	movl	12+FSZ(%esp), %ebx	/* fn arg */
-	movl	 0+FSZ(%esp), %eax	/* fn */
-	lea	-8(%ecx), %ecx		/* make space on stack */
-	movl	%ebx, 4(%ecx)		/*   fn arg */
-	movl	%eax, 0(%ecx)		/*   fn */
-
-	/* get other args to clone */
-	movl	 8+FSZ(%esp), %ebx	/* syscall arg1: flags */
-	movl	20+FSZ(%esp), %edx	/* syscall arg3: parent tid * */
-	movl	16+FSZ(%esp), %edi	/* syscall arg4: child tid * */
-	movl	24+FSZ(%esp), %esi	/* syscall arg5: tls_ptr * */
-	movl	$__NR_clone, %eax
-	int	$0x80			/* clone() */
-	testl	%eax, %eax		/* child if retval == 0 */
-	jnz	1f
-
-	/* CHILD - call thread function */
-	popl	%eax
-	call	*%eax			/* call fn */
-
-	/* exit with result */
-	movl	%eax, %ebx		/* arg1: return value from fn */
-	movl	$__NR_exit, %eax
-	int	$0x80
-
-	/* Hm, exit returned */
-	ud2
-		
-1:	/* PARENT or ERROR */
-	pop	%edi
-	pop	%ebx
-	ret
-#undef FSZ
 	
 .globl VG_(sigreturn)
 VG_(sigreturn):
@@ -163,7 +65,8 @@
 	
 	Prototype:
 
-	Int VGA_(_client_syscall)(Int syscallno,		// 0
+	Int VGA_(do_syscall_for_client_WRK)(
+	                          Int syscallno,		// 0
 				  void* guest_state,		// 4
 				  const vki_sigset_t *sysmask,	// 8
 				  const vki_sigset_t *postmask,	// 12
@@ -174,8 +77,8 @@
 /* from vki_arch.h */	
 #define VKI_SIG_SETMASK	2
 	
-.globl VGA_(_client_syscall)
-VGA_(_client_syscall):
+.globl VGA_(do_syscall_for_client_WRK)
+VGA_(do_syscall_for_client_WRK):
 	/* save callee-saved regs */
 	push	%esi
 	push	%edi
@@ -234,8 +137,9 @@
 	ret
 
 .section .rodata
-/* export the ranges so that VGA_(interrupted_syscall) can do the
-	right thing */
+/* export the ranges so that
+   VG_(fixup_guest_state_after_syscall_interrupted) can do the
+   right thing */
 	
 .globl VGA_(blksys_setup)
 .globl VGA_(blksys_restart)
diff --git a/coregrind/m_syscalls/syscalls-amd64-linux.c b/coregrind/m_syscalls/syscalls-amd64-linux.c
index 355034b..62b15dc 100644
--- a/coregrind/m_syscalls/syscalls-amd64-linux.c
+++ b/coregrind/m_syscalls/syscalls-amd64-linux.c
@@ -609,7 +609,7 @@
 
       /* Thread creation was successful; let the child have the chance
          to run */
-      VG_(vg_yield)();
+      XXX FIXME VG_(vg_yield)();
    }
 }
 
@@ -628,7 +628,7 @@
    VG_(sigframe_destroy)(tid, True);
 
    /* Keep looking for signals until there are none */
-   VG_(poll_signals)(tid);
+   XXX FIXME VG_(poll_signals)(tid);
 
    /* placate return-must-be-set assertion */
    SET_RESULT(RES);
diff --git a/coregrind/m_syscalls/syscalls.c b/coregrind/m_syscalls/syscalls-generic.c
similarity index 66%
rename from coregrind/m_syscalls/syscalls.c
rename to coregrind/m_syscalls/syscalls-generic.c
index faa6514..e473ed9 100644
--- a/coregrind/m_syscalls/syscalls.c
+++ b/coregrind/m_syscalls/syscalls-generic.c
@@ -1,6 +1,6 @@
 
 /*--------------------------------------------------------------------*/
-/*--- Handle system calls.                              syscalls.c ---*/
+/*--- Wrappers for generic Unix system calls    syscalls-generic.c ---*/
 /*--------------------------------------------------------------------*/
 
 /*
@@ -32,91 +32,21 @@
 #include "pub_core_debuglog.h"
 #include "pub_core_aspacemgr.h"
 #include "pub_core_libcbase.h"
-#include "pub_core_libcassert.h"
-#include "pub_core_libcfile.h"
 #include "pub_core_libcprint.h"
+#include "pub_core_libcfile.h"
+#include "pub_core_libcassert.h"
 #include "pub_core_main.h"
-#include "pub_core_profile.h"
 #include "pub_core_stacktrace.h"
-#include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
-#include "priv_syscalls.h"
+#include "pub_core_options.h"
+#include "pub_core_signals.h"
+#include "pub_core_syscalls.h"
 
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-generic.h"
 
-/* All system calls are channelled through here, doing two things:
+#include "vki_unistd.h"              /* for the __NR_* constants */
 
-   * notify the tool of the events (mem/reg reads, writes) happening
-
-   * perform the syscall, usually by passing it along to the kernel
-     unmodified.
-
-   A magical piece of assembly code, VG_(do_syscall)(), in syscall-$PLATFORM.S
-   does the tricky bit of passing a syscall to the kernel, whilst
-   having the simulator retain control.
-*/
-
-/* ---------------------------------------------------------------------
-   A simple atfork() facility for Valgrind's internal use
-   ------------------------------------------------------------------ */
-
-struct atfork {
-   vg_atfork_t	pre;
-   vg_atfork_t	parent;
-   vg_atfork_t	child;
-};
-
-#define VG_MAX_ATFORK	10
-
-static struct atfork atforks[VG_MAX_ATFORK];
-static Int n_atfork;
-
-void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
-{
-   Int i;
-
-   for(i = 0; i < n_atfork; i++) {
-      if (atforks[i].pre == pre &&
-	  atforks[i].parent == parent &&
-	  atforks[i].child == child)
-	 return;
-   }
-
-   if (n_atfork >= VG_MAX_ATFORK)
-      VG_(core_panic)("Too many VG_(atfork) handlers requested: raise VG_MAX_ATFORK");
-
-   atforks[n_atfork].pre    = pre;
-   atforks[n_atfork].parent = parent;
-   atforks[n_atfork].child  = child;
-
-   n_atfork++;
-}
-
-void VG_(do_atfork_pre)(ThreadId tid)
-{
-   Int i;
-
-   for(i = 0; i < n_atfork; i++)
-      if (atforks[i].pre != NULL)
-	 (*atforks[i].pre)(tid);
-}
-
-void VG_(do_atfork_parent)(ThreadId tid)
-{
-   Int i;
-
-   for(i = 0; i < n_atfork; i++)
-      if (atforks[i].parent != NULL)
-	 (*atforks[i].parent)(tid);
-}
-
-void VG_(do_atfork_child)(ThreadId tid)
-{
-   Int i;
-
-   for(i = 0; i < n_atfork; i++)
-      if (atforks[i].child != NULL)
-	 (*atforks[i].child)(tid);
-}
 
 /* return true if address range entirely contained within client
    address space */
@@ -143,8 +73,9 @@
 		  syscallname, start, end, cl_base, VG_(client_end), ret);
 
    if (!ret && syscallname != NULL) {
-      VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried to modify addresses %p-%p",
-		   syscallname, start, end);
+      VG_(message)(Vg_UserMsg, "Warning: client syscall %s tried "
+                               "to modify addresses %p-%p",
+                               syscallname, start, end);
 
       if (VG_(clo_verbosity) > 1) {
          VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
@@ -181,8 +112,8 @@
    *a = ra;
 }
 
-static
-void mmap_segment ( Addr a, SizeT len, UInt prot, UInt mm_flags, Int fd, ULong offset )
+void VG_(mmap_segment) ( Addr a, SizeT len, UInt prot, 
+                         UInt mm_flags, Int fd, ULong offset )
 {
    Bool rr, ww, xx;
    UInt flags;
@@ -207,21 +138,21 @@
 }
 
 static 
-Addr mremap_segment ( Addr old_addr, SizeT old_size,
-		      Addr new_addr, SizeT new_size,
-		      UInt flags, ThreadId tid)
+SysRes mremap_segment ( Addr old_addr, SizeT old_size,
+                        Addr new_addr, SizeT new_size,
+                        UInt flags, ThreadId tid)
 {
-   Addr ret;
+   SysRes ret;
    Segment *seg, *next;
 
    old_size = VG_PGROUNDUP(old_size);
    new_size = VG_PGROUNDUP(new_size);
 
    if (VG_PGROUNDDN(old_addr) != old_addr)
-      return -VKI_EINVAL;
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
 
    if (!VG_(valid_client_addr)(old_addr, old_size, tid, "mremap(old_addr)"))
-      return -VKI_EFAULT;
+      return VG_(mk_SysRes_Error)( VKI_EFAULT );
 
    /* fixed at the current address means we don't move it */
    if ((flags & VKI_MREMAP_FIXED) && (old_addr == new_addr))
@@ -229,28 +160,28 @@
 
    if (flags & VKI_MREMAP_FIXED) {
       if (VG_PGROUNDDN(new_addr) != new_addr)
-	 return -VKI_EINVAL;
+	 return VG_(mk_SysRes_Error)( VKI_EINVAL );
 
       if (!VG_(valid_client_addr)(new_addr, new_size, tid, "mremap(new_addr)"))
-	 return -VKI_ENOMEM;
+	 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
 
       /* check for overlaps */
       if ((old_addr < (new_addr+new_size) &&
 	   (old_addr+old_size) > new_addr) ||
 	  (new_addr < (old_addr+new_size) &&
 	   (new_addr+new_size) > old_addr))
-	 return -VKI_EINVAL;
+	 return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
    /* Do nothing */
    if (!(flags & VKI_MREMAP_FIXED) && new_size == old_size)
-      return old_addr;
+      return VG_(mk_SysRes_Success)( old_addr );
 
    seg = VG_(find_segment)(old_addr);
 
    /* range must be contained within segment */
    if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
-      return -VKI_EINVAL;
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
 
    next = VG_(find_segment_above_mapped)(old_addr);
 
@@ -264,7 +195,8 @@
       Addr a;
       
       if ((flags & (VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE)) == 0)
-	 return -VKI_ENOMEM;	/* not allowed to move */
+         /* not allowed to move */
+	 return VG_(mk_SysRes_Error)( VKI_ENOMEM ); 
 
       if ((flags & VKI_MREMAP_FIXED) == 0)
 	  new_addr = 0;
@@ -272,19 +204,18 @@
       a = VG_(find_map_space)(new_addr, new_size, True);
 
       if ((flags & VKI_MREMAP_FIXED) && a != new_addr)
-	 return -VKI_ENOMEM;	/* didn't find the place we wanted */
+         /* didn't find the place we wanted */
+	 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
 
       new_addr = a;
-      ret = a;
 
       /* we've nailed down the location */
-      flags |=  VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
+      flags |= VKI_MREMAP_FIXED|VKI_MREMAP_MAYMOVE;
 
       ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size, 
 			     flags, new_addr);
 
-      if (ret != new_addr) {
-	 vg_assert(VG_(is_kerror)(ret));
+      if (ret.isError) {
 	 return ret;
       }
 
@@ -307,7 +238,7 @@
       VG_(munmap)((void *)old_addr, old_size);
    } else {
       /* staying in place */
-      ret = old_addr;
+      ret = VG_(mk_SysRes_Success)( old_addr );
 
       if (new_size < old_size) {
 	 VG_TRACK(die_mem_munmap, old_addr+new_size, old_size-new_size);
@@ -323,7 +254,7 @@
 	 ret = VG_(do_syscall5)(__NR_mremap, old_addr, old_size, new_size, 
 			        flags, 0);
 
-	 if (ret != old_addr)
+	 if (ret.isError || (!ret.isError && ret.val != old_addr))
 	    return ret;
 
 	 VG_TRACK(new_mem_mmap, old_addr+old_size, new_size-old_size,
@@ -343,34 +274,9 @@
 }
 
 
-/* Is this a Linux kernel error return value? */
-/* From:
-   http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
-   linux/i386/sysdep.h?
-   rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
-
-   \begin{quote}:
-
-   Linux uses a negative return value to indicate syscall errors,
-   unlike most Unices, which use the condition codes' carry flag.
-
-   Since version 2.1 the return value of a system call might be
-   negative even if the call succeeded.  E.g., the 'lseek' system call
-   might return a large offset.  Therefore we must not anymore test
-   for < 0, but test for a real error by making sure the value in %eax
-   is a real error number.  Linus said he will make sure the no syscall
-   returns a value in -1 .. -4095 as a valid result so we can safely
-   test with -4095.  
-
-   END QUOTE
-*/
-Bool VG_(is_kerror) ( Word res )
-{
-   if (res >= -4095 && res <= -1)
-      return True;
-   else
-      return False;
-}
+/* ---------------------------------------------------------------------
+   File-descriptor tracking
+   ------------------------------------------------------------------ */
 
 /* One of these is allocated for each open file descriptor.  */
 
@@ -527,11 +433,9 @@
    return name;
 }
 
-
 /*
  * Try get some details about a socket.
  */
-
 static void
 getsockdetails(int fd)
 {
@@ -773,8 +677,8 @@
 
 static
 void pre_mem_read_sockaddr ( ThreadId tid,
-			     Char *description,
-			     struct vki_sockaddr *sa, UInt salen )
+                             Char *description,
+                             struct vki_sockaddr *sa, UInt salen )
 {
    Char *outmsg;
 
@@ -858,11 +762,10 @@
 }
 
 static 
-void buf_and_len_post_check( ThreadId tid, Int res,
+void buf_and_len_post_check( ThreadId tid, SysRes res,
                              Addr buf_p, Addr buflen_p, Char* s )
 {
-   if (!VG_(is_kerror)(res) && VG_(tdict).track_post_mem_write) 
-   {
+   if (!res.isError && VG_(tdict).track_post_mem_write) {
       UInt buflen_out = deref_UInt( tid, buflen_p, s);
       if (buflen_out > 0 && buf_p != (Addr)NULL) {
          VG_(tdict).track_post_mem_write( Vg_CoreSysCall, tid, buf_p, buflen_out );
@@ -1001,13 +904,14 @@
                   arg3, 2*sizeof(int) );
 }
 
-UWord 
+SysRes
 VG_(generic_POST_sys_socketpair) ( ThreadId tid,
-                                   UWord res,
+                                   SysRes res,
                                    UWord arg0, UWord arg1, 
                                    UWord arg2, UWord arg3 )
 {
-   UWord r = res;
+   SysRes r = res;
+   vg_assert(!res.isError); /* guaranteed by caller */
    Int fd1 = ((Int*)arg3)[0];
    Int fd2 = ((Int*)arg3)[1];
    POST_MEM_WRITE( arg3, 2*sizeof(int) );
@@ -1015,7 +919,7 @@
        !VG_(fd_allowed)(fd2, "socketcall.socketpair", tid, True)) {
       VG_(close)(fd1);
       VG_(close)(fd2);
-      r = -VKI_EMFILE;
+      r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       POST_MEM_WRITE( arg3, 2*sizeof(int) );
       if (VG_(clo_track_fds)) {
@@ -1028,16 +932,17 @@
 
 /* ------ */
 
-UWord 
-VG_(generic_POST_sys_socket) ( ThreadId tid, UWord res )
+SysRes 
+VG_(generic_POST_sys_socket) ( ThreadId tid, SysRes res )
 {
-   UWord r = res;
-   if (!VG_(fd_allowed)(res, "socket", tid, True)) {
-      VG_(close)(res);
-      r = -VKI_EMFILE;
+   SysRes r = res;
+   vg_assert(!res.isError); /* guaranteed by caller */
+   if (!VG_(fd_allowed)(res.val, "socket", tid, True)) {
+      VG_(close)(res.val);
+      r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       if (VG_(clo_track_fds))
-         VG_(record_fd_open)(tid, res, NULL);
+         VG_(record_fd_open)(tid, res.val, NULL);
    }
    return r;
 }
@@ -1071,15 +976,16 @@
                               "socketcall.accept(addrlen_in)" );
 }
 
-UWord 
+SysRes 
 VG_(generic_POST_sys_accept) ( ThreadId tid,
-                               UWord res,
+                               SysRes res,
                                UWord arg0, UWord arg1, UWord arg2 )
 {
-   UWord r = res;
-   if (!VG_(fd_allowed)(res, "accept", tid, True)) {
-      VG_(close)(res);
-      r = -VKI_EMFILE;
+   SysRes r = res;
+   vg_assert(!res.isError); /* guaranteed by caller */
+   if (!VG_(fd_allowed)(res.val, "accept", tid, True)) {
+      VG_(close)(res.val);
+      r = VG_(mk_SysRes_Error)( VKI_EMFILE );
    } else {
       Addr addr_p     = arg1;
       Addr addrlen_p  = arg2;
@@ -1087,7 +993,7 @@
          buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
                                   "socketcall.accept(addrlen_out)" );
       if (VG_(clo_track_fds))
-          VG_(record_fd_open)(tid, res, NULL);
+          VG_(record_fd_open)(tid, res.val, NULL);
    }
    return r;
 }
@@ -1146,7 +1052,7 @@
 
 void 
 VG_(generic_POST_sys_recvfrom) ( ThreadId tid,
-                                 UWord res,
+                                 SysRes res,
                                  UWord arg0, UWord arg1, UWord arg2,
                                  UWord arg3, UWord arg4, UWord arg5 )
 {
@@ -1155,6 +1061,7 @@
    Addr from_p     = arg4;
    Addr fromlen_p  = arg5;
 
+   vg_assert(!res.isError); /* guaranteed by caller */
    if (from_p != (Addr)NULL) 
       buf_and_len_post_check ( tid, res, from_p, fromlen_p,
                                "socketcall.recvfrom(fromlen_out)" );
@@ -1239,12 +1146,13 @@
 
 void 
 VG_(generic_POST_sys_getsockopt) ( ThreadId tid,
-                                   UWord res,
+                                   SysRes res,
                                    UWord arg0, UWord arg1, UWord arg2,
                                    UWord arg3, UWord arg4 )
 {
    Addr optval_p  = arg3;
    Addr optlen_p  = arg4;
+   vg_assert(!res.isError); /* guaranteed by caller */
    if (optval_p != (Addr)NULL) 
       buf_and_len_post_check ( tid, res, optval_p, optlen_p,
                                "socketcall.getsockopt(optlen_out)" );
@@ -1267,11 +1175,12 @@
 
 void 
 VG_(generic_POST_sys_getsockname) ( ThreadId tid,
-                                    UWord res,
+                                    SysRes res,
                                     UWord arg0, UWord arg1, UWord arg2 )
 {
    Addr name_p     = arg1;
    Addr namelen_p  = arg2;
+   vg_assert(!res.isError); /* guaranteed by caller */
    buf_and_len_post_check ( tid, res, name_p, namelen_p,
                             "socketcall.getsockname(namelen_out)" );
 }
@@ -1293,11 +1202,12 @@
 
 void 
 VG_(generic_POST_sys_getpeername) ( ThreadId tid,
-                                    UWord res,
+                                    SysRes res,
                                     UWord arg0, UWord arg1, UWord arg2 )
 {
    Addr name_p     = arg1;
    Addr namelen_p  = arg2;
+   vg_assert(!res.isError); /* guaranteed by caller */
    buf_and_len_post_check ( tid, res, name_p, namelen_p,
                             "socketcall.getpeername(namelen_out)" );
 }
@@ -1326,7 +1236,6 @@
 
 void 
 VG_(generic_POST_sys_recvmsg) ( ThreadId tid,
-                                UWord res,
                                 UWord arg0, UWord arg1 )
 {
    struct vki_msghdr *msg = (struct vki_msghdr *)arg1;
@@ -1368,22 +1277,22 @@
 static
 UInt get_sem_count( Int semid )
 {
-  struct vki_semid_ds buf;
-  union vki_semun arg;
-  long res;
+   struct vki_semid_ds buf;
+   union vki_semun arg;
+   SysRes res;
 
-  arg.buf = &buf;
+   arg.buf = &buf;
 
-#ifdef __NR_semctl
-  res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
-#else
-  res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
-                         VKI_IPC_STAT, (UWord)&arg);
-#endif
-  if ( VG_(is_kerror)(res) )
-    return 0;
+#  ifdef __NR_semctl
+   res = VG_(do_syscall4)(__NR_semctl, semid, 0, VKI_IPC_STAT, *(UWord *)&arg);
+#  else
+   res = VG_(do_syscall5)(__NR_ipc, 3 /* IPCOP_semctl */, semid, 0,
+                          VKI_IPC_STAT, (UWord)&arg);
+# endif
+   if (res.isError)
+      return 0;
 
-  return buf.sem_nsems;
+   return buf.sem_nsems;
 }
 
 void
@@ -1568,15 +1477,15 @@
 static
 UInt get_shm_size ( Int shmid )
 {
-#ifdef __NR_shmctl
+#  ifdef __NR_shmctl
    struct vki_shmid64_ds buf;
-   long __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
-#else
+   SysRes __res = VG_(do_syscall3)(__NR_shmctl, shmid, VKI_IPC_STAT, (UWord)&buf);
+#  else
    struct vki_shmid_ds buf;
-   long __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
+   SysRes __res = VG_(do_syscall5)(__NR_ipc, 24 /* IPCOP_shmctl */, shmid,
                                  VKI_IPC_STAT, 0, (UWord)&buf);
-#endif
-   if ( VG_(is_kerror) ( __res ) )
+#  endif
+   if (__res.isError)
       return 0;
  
    return buf.shm_segsz;
@@ -1736,94 +1645,94 @@
    XXX: some of these are arch-specific, and should be factored out.
 */
 
-#define PRE(name, f)     PRE_TEMPLATE( , vgArch_gen, name, f)
-#define POST(name)      POST_TEMPLATE( , vgArch_gen, name)
+#define PRE(name)      DEFN_PRE_TEMPLATE(generic, name)
+#define POST(name)     DEFN_POST_TEMPLATE(generic, name)
 
-// Combine two 32-bit values into a 64-bit value
-#define LOHI64(lo,hi)   ( (lo) | ((ULong)(hi) << 32) )
+//zz // Combine two 32-bit values into a 64-bit value
+//zz #define LOHI64(lo,hi)   ( (lo) | ((ULong)(hi) << 32) )
+//zz 
+//zz //PRE(sys_exit_group, Special)
+//zz //{
+//zz //   VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
+//zz //}
 
-//PRE(sys_exit_group, Special)
-//{
-//   VG_(core_panic)("syscall exit_group() not caught by the scheduler?!");
-//}
-
-PRE(sys_exit, Special)
+PRE(sys_exit)
 {
+   ThreadState* tst;
    /* simple; just make this thread exit */
    PRINT("exit( %d )", ARG1);
    PRE_REG_READ1(void, "exit", int, exitcode);
+   tst = VG_(get_ThreadState)(tid);
+   /* Set the thread's status to be exiting, then claim that the
+      syscall succeeded. */
    tst->exitreason = VgSrc_ExitSyscall;
    tst->os_state.exitcode = ARG1;
-   /* exit doesn't return anything (it doesn't return.)
-      Nevertheless, if we don't do this, the result-not-assigned-
-      yet-you-said-you-were-Special assertion in the main syscall
-      handling logic will fire.  Hence ..
-   */
-   SET_RESULT(0);
+   SET_STATUS_Success(0);
 }
 
-PRE(sys_sched_yield, MayBlock)
-{
-   PRINT("sched_yield()");
-   PRE_REG_READ0(long, "sys_sched_yield");
-}
+//zz PRE(sys_sched_yield, SfMayBlock)
+//zz {
+//zz    PRINT("sched_yield()");
+//zz    PRE_REG_READ0(long, "sys_sched_yield");
+//zz }
 
-PRE(sys_ni_syscall, Special)
+PRE(sys_ni_syscall)
 {
    PRINT("non-existent syscall! (ni_syscall)");
    PRE_REG_READ0(long, "ni_syscall");
-   SET_RESULT( -VKI_ENOSYS );
+   SET_STATUS_Failure( VKI_ENOSYS );
 }
 
-PRE(sys_set_tid_address, 0)
-{
-   PRINT("sys_set_tid_address ( %p )", ARG1);
-   PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
-}
+//zz PRE(sys_set_tid_address, 0)
+//zz {
+//zz    PRINT("sys_set_tid_address ( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "set_tid_address", int *, tidptr);
+//zz }
+//zz 
+//zz PRE(sys_iopl, 0)
+//zz {
+//zz    PRINT("sys_iopl ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "iopl", unsigned long, level);
+//zz }
+//zz 
+//zz PRE(sys_setxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
+//zz          ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
+//zz    PRE_REG_READ5(long, "setxattr",
+//zz                  char *, path, char *, name,
+//zz                  void *, value, vki_size_t, size, int, flags);
+//zz    PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
+//zz    PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
+//zz    PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
+//zz }
+//zz 
+//zz PRE(sys_lsetxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
+//zz          ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
+//zz    PRE_REG_READ5(long, "lsetxattr",
+//zz                  char *, path, char *, name,
+//zz                  void *, value, vki_size_t, size, int, flags);
+//zz    PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
+//zz    PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
+//zz    PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
+//zz }
+//zz 
+//zz PRE(sys_fsetxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
+//zz          ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
+//zz    PRE_REG_READ5(long, "fsetxattr",
+//zz                  int, fd, char *, name, void *, value,
+//zz                  vki_size_t, size, int, flags);
+//zz    PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
+//zz    PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
+//zz }
 
-PRE(sys_iopl, 0)
+PRE(sys_getxattr)
 {
-   PRINT("sys_iopl ( %d )", ARG1);
-   PRE_REG_READ1(long, "iopl", unsigned long, level);
-}
-
-PRE(sys_setxattr, MayBlock)
-{
-   PRINT("sys_setxattr ( %p, %p, %p, %llu, %d )",
-         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
-   PRE_REG_READ5(long, "setxattr",
-                 char *, path, char *, name,
-                 void *, value, vki_size_t, size, int, flags);
-   PRE_MEM_RASCIIZ( "setxattr(path)", ARG1 );
-   PRE_MEM_RASCIIZ( "setxattr(name)", ARG2 );
-   PRE_MEM_READ( "setxattr(value)", ARG3, ARG4 );
-}
-
-PRE(sys_lsetxattr, MayBlock)
-{
-   PRINT("sys_lsetxattr ( %p, %p, %p, %llu, %d )",
-         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
-   PRE_REG_READ5(long, "lsetxattr",
-                 char *, path, char *, name,
-                 void *, value, vki_size_t, size, int, flags);
-   PRE_MEM_RASCIIZ( "lsetxattr(path)", ARG1 );
-   PRE_MEM_RASCIIZ( "lsetxattr(name)", ARG2 );
-   PRE_MEM_READ( "lsetxattr(value)", ARG3, ARG4 );
-}
-
-PRE(sys_fsetxattr, MayBlock)
-{
-   PRINT("sys_fsetxattr ( %d, %p, %p, %llu, %d )",
-         ARG1, ARG2, ARG3, (ULong)ARG4, ARG5);
-   PRE_REG_READ5(long, "fsetxattr",
-                 int, fd, char *, name, void *, value,
-                 vki_size_t, size, int, flags);
-   PRE_MEM_RASCIIZ( "fsetxattr(name)", ARG2 );
-   PRE_MEM_READ( "fsetxattr(value)", ARG3, ARG4 );
-}
-
-PRE(sys_getxattr, MayBlock)
-{
+   *flags |= SfMayBlock;
    PRINT("sys_getxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
    PRE_REG_READ4(ssize_t, "getxattr",
                  char *, path, char *, name, void *, value, vki_size_t, size);
@@ -1834,266 +1743,268 @@
 
 POST(sys_getxattr)
 {
+   vg_assert(SUCCESS);
    if (RES > 0 && ARG3 != (Addr)NULL) {
       POST_MEM_WRITE( ARG3, RES );
    }
 }
 
-PRE(sys_lgetxattr, MayBlock)
+//zz PRE(sys_lgetxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
+//zz    PRE_REG_READ4(ssize_t, "lgetxattr",
+//zz                  char *, path, char *, name, void *, value, vki_size_t, size);
+//zz    PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
+//zz    PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
+//zz    PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
+//zz }
+//zz 
+//zz POST(sys_lgetxattr)
+//zz {
+//zz    if (RES > 0 && ARG3 != (Addr)NULL) {
+//zz       POST_MEM_WRITE( ARG3, RES );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_fgetxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
+//zz    PRE_REG_READ4(ssize_t, "fgetxattr",
+//zz                  int, fd, char *, name, void *, value, vki_size_t, size);
+//zz    PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
+//zz    PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
+//zz }
+//zz 
+//zz POST(sys_fgetxattr)
+//zz {
+//zz    if (RES > 0 && ARG3 != (Addr)NULL)
+//zz       POST_MEM_WRITE( ARG3, RES );
+//zz }
+//zz 
+//zz PRE(sys_listxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
+//zz    PRE_REG_READ3(ssize_t, "listxattr",
+//zz                  char *, path, char *, list, vki_size_t, size);
+//zz    PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
+//zz    PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
+//zz }
+//zz 
+//zz POST(sys_listxattr)
+//zz {
+//zz    if (RES > 0 && ARG2 != (Addr)NULL)
+//zz       POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz 
+//zz PRE(sys_llistxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
+//zz    PRE_REG_READ3(ssize_t, "llistxattr",
+//zz                  char *, path, char *, list, vki_size_t, size);
+//zz    PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
+//zz    PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
+//zz }
+//zz 
+//zz POST(sys_llistxattr)
+//zz {
+//zz    if (RES > 0 && ARG2 != (Addr)NULL)
+//zz       POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz 
+//zz PRE(sys_flistxattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
+//zz    PRE_REG_READ3(ssize_t, "flistxattr",
+//zz                  int, fd, char *, list, vki_size_t, size);
+//zz    PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
+//zz }
+//zz 
+//zz POST(sys_flistxattr)
+//zz {
+//zz    if (RES > 0 && ARG2 != (Addr)NULL)
+//zz       POST_MEM_WRITE( ARG2, RES );
+//zz }
+//zz 
+//zz PRE(sys_removexattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
+//zz    PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
+//zz    PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
+//zz }
+//zz 
+//zz PRE(sys_lremovexattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
+//zz    PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
+//zz    PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
+//zz }
+//zz 
+//zz PRE(sys_fremovexattr, SfMayBlock)
+//zz {
+//zz    PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
+//zz    PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
+//zz }
+//zz 
+//zz PRE(sys_quotactl, 0)
+//zz {
+//zz    PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
+//zz    PRE_REG_READ4(long, "quotactl",
+//zz                  unsigned int, cmd, const char *, special, vki_qid_t, id,
+//zz                  void *, addr);
+//zz    PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
+//zz }
+//zz 
+//zz // XXX: this wrapper is only suitable for 32-bit platforms
+//zz PRE(sys_lookup_dcookie, 0)
+//zz {
+//zz    PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
+//zz    PRE_REG_READ4(long, "lookup_dcookie",
+//zz                  vki_u32, cookie_low32, vki_u32, cookie_high32,
+//zz                  char *, buf, vki_size_t, len);
+//zz    PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
+//zz }
+//zz 
+//zz POST(sys_lookup_dcookie)
+//zz {
+//zz    if (ARG3 != (Addr)NULL)
+//zz       POST_MEM_WRITE( ARG3, RES);
+//zz }
+//zz 
+//zz PRE(sys_fsync, SfMayBlock)
+//zz {
+//zz    PRINT("sys_fsync ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "fsync", unsigned int, fd);
+//zz }
+//zz 
+//zz PRE(sys_fdatasync, SfMayBlock)
+//zz {
+//zz    PRINT("sys_fdatasync ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
+//zz }
+//zz 
+//zz PRE(sys_msync, SfMayBlock)
+//zz {
+//zz    PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "msync",
+//zz                  unsigned long, start, vki_size_t, length, int, flags);
+//zz    PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
+//zz }
+//zz 
+//zz // Nb: getpmsg() and putpmsg() are special additional syscalls used in early
+//zz // versions of LiS (Linux Streams).  They are not part of the kernel.
+//zz // Therefore, we have to provide this type ourself, rather than getting it
+//zz // from the kernel sources.
+//zz struct vki_pmsg_strbuf {
+//zz    int     maxlen;         /* no. of bytes in buffer */
+//zz    int     len;            /* no. of bytes returned */
+//zz    vki_caddr_t buf;        /* pointer to data */
+//zz };
+//zz 
+//zz PRE(sys_getpmsg, SfMayBlock)
+//zz {
+//zz    /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
+//zz    struct vki_pmsg_strbuf *ctrl;
+//zz    struct vki_pmsg_strbuf *data;
+//zz    PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz    PRE_REG_READ5(int, "getpmsg",
+//zz                  int, fd, struct strbuf *, ctrl, struct strbuf *, data, 
+//zz                  int *, bandp, int *, flagsp);
+//zz    ctrl = (struct vki_pmsg_strbuf *)ARG2;
+//zz    data = (struct vki_pmsg_strbuf *)ARG3;
+//zz    if (ctrl && ctrl->maxlen > 0)
+//zz       PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
+//zz    if (data && data->maxlen > 0)
+//zz       PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
+//zz    if (ARG4)
+//zz       PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
+//zz    if (ARG5)
+//zz       PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
+//zz }
+//zz 
+//zz POST(sys_getpmsg)
+//zz {
+//zz    struct vki_pmsg_strbuf *ctrl;
+//zz    struct vki_pmsg_strbuf *data;
+//zz 
+//zz    ctrl = (struct vki_pmsg_strbuf *)ARG2;
+//zz    data = (struct vki_pmsg_strbuf *)ARG3;
+//zz    if (RES == 0 && ctrl && ctrl->len > 0) {
+//zz       POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
+//zz    }
+//zz    if (RES == 0 && data && data->len > 0) {
+//zz       POST_MEM_WRITE( (Addr)data->buf, data->len);
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_putpmsg, SfMayBlock)
+//zz {
+//zz    /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
+//zz    struct vki_pmsg_strbuf *ctrl;
+//zz    struct vki_pmsg_strbuf *data;
+//zz    PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz    PRE_REG_READ5(int, "putpmsg",
+//zz                  int, fd, struct strbuf *, ctrl, struct strbuf *, data, 
+//zz                  int, band, int, flags);
+//zz    ctrl = (struct vki_pmsg_strbuf *)ARG2;
+//zz    data = (struct vki_pmsg_strbuf *)ARG3;
+//zz    if (ctrl && ctrl->len > 0)
+//zz       PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
+//zz    if (data && data->len > 0)
+//zz       PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
+//zz }
+//zz 
+//zz PRE(sys_getitimer, 0)
+//zz {
+//zz    PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
+//zz    PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
+//zz }
+//zz 
+//zz POST(sys_getitimer)
+//zz {
+//zz    if (ARG2 != (Addr)NULL) {
+//zz       POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_setitimer, 0)
+//zz {
+//zz    PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "setitimer", 
+//zz                  int, which,
+//zz                  struct itimerval *, value, struct itimerval *, ovalue);
+//zz    if (ARG2 != (Addr)NULL)
+//zz       PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
+//zz    if (ARG3 != (Addr)NULL)
+//zz       PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
+//zz }
+//zz 
+//zz POST(sys_setitimer)
+//zz {
+//zz    if (ARG3 != (Addr)NULL) {
+//zz       POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_chroot, 0)
+//zz {
+//zz    PRINT("sys_chroot ( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "chroot", const char *, path);
+//zz    PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
+//zz }
+
+PRE(sys_madvise)
 {
-   PRINT("sys_lgetxattr ( %p, %p, %p, %llu )", ARG1,ARG2,ARG3, (ULong)ARG4);
-   PRE_REG_READ4(ssize_t, "lgetxattr",
-                 char *, path, char *, name, void *, value, vki_size_t, size);
-   PRE_MEM_RASCIIZ( "lgetxattr(path)", ARG1 );
-   PRE_MEM_RASCIIZ( "lgetxattr(name)", ARG2 );
-   PRE_MEM_WRITE( "lgetxattr(value)", ARG3, ARG4 );
-}
-
-POST(sys_lgetxattr)
-{
-   if (RES > 0 && ARG3 != (Addr)NULL) {
-      POST_MEM_WRITE( ARG3, RES );
-   }
-}
-
-PRE(sys_fgetxattr, MayBlock)
-{
-   PRINT("sys_fgetxattr ( %d, %p, %p, %llu )", ARG1, ARG2, ARG3, (ULong)ARG4);
-   PRE_REG_READ4(ssize_t, "fgetxattr",
-                 int, fd, char *, name, void *, value, vki_size_t, size);
-   PRE_MEM_RASCIIZ( "fgetxattr(name)", ARG2 );
-   PRE_MEM_WRITE( "fgetxattr(value)", ARG3, ARG4 );
-}
-
-POST(sys_fgetxattr)
-{
-   if (RES > 0 && ARG3 != (Addr)NULL)
-      POST_MEM_WRITE( ARG3, RES );
-}
-
-PRE(sys_listxattr, MayBlock)
-{
-   PRINT("sys_listxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
-   PRE_REG_READ3(ssize_t, "listxattr",
-                 char *, path, char *, list, vki_size_t, size);
-   PRE_MEM_RASCIIZ( "listxattr(path)", ARG1 );
-   PRE_MEM_WRITE( "listxattr(list)", ARG2, ARG3 );
-}
-
-POST(sys_listxattr)
-{
-   if (RES > 0 && ARG2 != (Addr)NULL)
-      POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_llistxattr, MayBlock)
-{
-   PRINT("sys_llistxattr ( %p, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
-   PRE_REG_READ3(ssize_t, "llistxattr",
-                 char *, path, char *, list, vki_size_t, size);
-   PRE_MEM_RASCIIZ( "llistxattr(path)", ARG1 );
-   PRE_MEM_WRITE( "llistxattr(list)", ARG2, ARG3 );
-}
-
-POST(sys_llistxattr)
-{
-   if (RES > 0 && ARG2 != (Addr)NULL)
-      POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_flistxattr, MayBlock)
-{
-   PRINT("sys_flistxattr ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
-   PRE_REG_READ3(ssize_t, "flistxattr",
-                 int, fd, char *, list, vki_size_t, size);
-   PRE_MEM_WRITE( "flistxattr(list)", ARG2, ARG3 );
-}
-
-POST(sys_flistxattr)
-{
-   if (RES > 0 && ARG2 != (Addr)NULL)
-      POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_removexattr, MayBlock)
-{
-   PRINT("sys_removexattr ( %p, %p )", ARG1, ARG2);
-   PRE_REG_READ2(long, "removexattr", char *, path, char *, name);
-   PRE_MEM_RASCIIZ( "removexattr(path)", ARG1 );
-   PRE_MEM_RASCIIZ( "removexattr(name)", ARG2 );
-}
-
-PRE(sys_lremovexattr, MayBlock)
-{
-   PRINT("sys_lremovexattr ( %p, %p )", ARG1, ARG2);
-   PRE_REG_READ2(long, "lremovexattr", char *, path, char *, name);
-   PRE_MEM_RASCIIZ( "lremovexattr(path)", ARG1 );
-   PRE_MEM_RASCIIZ( "lremovexattr(name)", ARG2 );
-}
-
-PRE(sys_fremovexattr, MayBlock)
-{
-   PRINT("sys_fremovexattr ( %d, %p )", ARG1, ARG2);
-   PRE_REG_READ2(long, "fremovexattr", int, fd, char *, name);
-   PRE_MEM_RASCIIZ( "fremovexattr(name)", ARG2 );
-}
-
-PRE(sys_quotactl, 0)
-{
-   PRINT("sys_quotactl (0x%x, %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3, ARG4);
-   PRE_REG_READ4(long, "quotactl",
-                 unsigned int, cmd, const char *, special, vki_qid_t, id,
-                 void *, addr);
-   PRE_MEM_RASCIIZ( "quotactl(special)", ARG2 );
-}
-
-// XXX: this wrapper is only suitable for 32-bit platforms
-PRE(sys_lookup_dcookie, 0)
-{
-   PRINT("sys_lookup_dcookie (0x%llx, %p, %d)", LOHI64(ARG1,ARG2), ARG3, ARG4);
-   PRE_REG_READ4(long, "lookup_dcookie",
-                 vki_u32, cookie_low32, vki_u32, cookie_high32,
-                 char *, buf, vki_size_t, len);
-   PRE_MEM_WRITE( "lookup_dcookie(buf)", ARG3, ARG4);
-}
-
-POST(sys_lookup_dcookie)
-{
-   if (ARG3 != (Addr)NULL)
-      POST_MEM_WRITE( ARG3, RES);
-}
-
-PRE(sys_fsync, MayBlock)
-{
-   PRINT("sys_fsync ( %d )", ARG1);
-   PRE_REG_READ1(long, "fsync", unsigned int, fd);
-}
-
-PRE(sys_fdatasync, MayBlock)
-{
-   PRINT("sys_fdatasync ( %d )", ARG1);
-   PRE_REG_READ1(long, "fdatasync", unsigned int, fd);
-}
-
-PRE(sys_msync, MayBlock)
-{
-   PRINT("sys_msync ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
-   PRE_REG_READ3(long, "msync",
-                 unsigned long, start, vki_size_t, length, int, flags);
-   PRE_MEM_READ( "msync(start)", ARG1, ARG2 );
-}
-
-// Nb: getpmsg() and putpmsg() are special additional syscalls used in early
-// versions of LiS (Linux Streams).  They are not part of the kernel.
-// Therefore, we have to provide this type ourself, rather than getting it
-// from the kernel sources.
-struct vki_pmsg_strbuf {
-   int     maxlen;         /* no. of bytes in buffer */
-   int     len;            /* no. of bytes returned */
-   vki_caddr_t buf;        /* pointer to data */
-};
-
-PRE(sys_getpmsg, MayBlock)
-{
-   /* LiS getpmsg from http://www.gcom.com/home/linux/lis/ */
-   struct vki_pmsg_strbuf *ctrl;
-   struct vki_pmsg_strbuf *data;
-   PRINT("sys_getpmsg ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
-   PRE_REG_READ5(int, "getpmsg",
-                 int, fd, struct strbuf *, ctrl, struct strbuf *, data, 
-                 int *, bandp, int *, flagsp);
-   ctrl = (struct vki_pmsg_strbuf *)ARG2;
-   data = (struct vki_pmsg_strbuf *)ARG3;
-   if (ctrl && ctrl->maxlen > 0)
-      PRE_MEM_WRITE( "getpmsg(ctrl)", (Addr)ctrl->buf, ctrl->maxlen);
-   if (data && data->maxlen > 0)
-      PRE_MEM_WRITE( "getpmsg(data)", (Addr)data->buf, data->maxlen);
-   if (ARG4)
-      PRE_MEM_WRITE( "getpmsg(bandp)", (Addr)ARG4, sizeof(int));
-   if (ARG5)
-      PRE_MEM_WRITE( "getpmsg(flagsp)", (Addr)ARG5, sizeof(int));
-}
-
-POST(sys_getpmsg)
-{
-   struct vki_pmsg_strbuf *ctrl;
-   struct vki_pmsg_strbuf *data;
-
-   ctrl = (struct vki_pmsg_strbuf *)ARG2;
-   data = (struct vki_pmsg_strbuf *)ARG3;
-   if (RES == 0 && ctrl && ctrl->len > 0) {
-      POST_MEM_WRITE( (Addr)ctrl->buf, ctrl->len);
-   }
-   if (RES == 0 && data && data->len > 0) {
-      POST_MEM_WRITE( (Addr)data->buf, data->len);
-   }
-}
-
-PRE(sys_putpmsg, MayBlock)
-{
-   /* LiS putpmsg from http://www.gcom.com/home/linux/lis/ */
-   struct vki_pmsg_strbuf *ctrl;
-   struct vki_pmsg_strbuf *data;
-   PRINT("sys_putpmsg ( %d, %p, %p, %d, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
-   PRE_REG_READ5(int, "putpmsg",
-                 int, fd, struct strbuf *, ctrl, struct strbuf *, data, 
-                 int, band, int, flags);
-   ctrl = (struct vki_pmsg_strbuf *)ARG2;
-   data = (struct vki_pmsg_strbuf *)ARG3;
-   if (ctrl && ctrl->len > 0)
-      PRE_MEM_READ( "putpmsg(ctrl)", (Addr)ctrl->buf, ctrl->len);
-   if (data && data->len > 0)
-      PRE_MEM_READ( "putpmsg(data)", (Addr)data->buf, data->len);
-}
-
-PRE(sys_getitimer, 0)
-{
-   PRINT("sys_getitimer ( %d, %p )", ARG1, ARG2);
-   PRE_REG_READ2(long, "getitimer", int, which, struct itimerval *, value);
-   PRE_MEM_WRITE( "getitimer(value)", ARG2, sizeof(struct vki_itimerval) );
-}
-
-POST(sys_getitimer)
-{
-   if (ARG2 != (Addr)NULL) {
-      POST_MEM_WRITE(ARG2, sizeof(struct vki_itimerval));
-   }
-}
-
-PRE(sys_setitimer, 0)
-{
-   PRINT("sys_setitimer ( %d, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "setitimer", 
-                 int, which,
-                 struct itimerval *, value, struct itimerval *, ovalue);
-   if (ARG2 != (Addr)NULL)
-      PRE_MEM_READ( "setitimer(value)", ARG2, sizeof(struct vki_itimerval) );
-   if (ARG3 != (Addr)NULL)
-      PRE_MEM_WRITE( "setitimer(ovalue)", ARG3, sizeof(struct vki_itimerval));
-}
-
-POST(sys_setitimer)
-{
-   if (ARG3 != (Addr)NULL) {
-      POST_MEM_WRITE(ARG3, sizeof(struct vki_itimerval));
-   }
-}
-
-PRE(sys_chroot, 0)
-{
-   PRINT("sys_chroot ( %p )", ARG1);
-   PRE_REG_READ1(long, "chroot", const char *, path);
-   PRE_MEM_RASCIIZ( "chroot(path)", ARG1 );
-}
-
-PRE(sys_madvise, MayBlock)
-{
+   *flags |= SfMayBlock;
    PRINT("sys_madvise ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
    PRE_REG_READ3(long, "madvise",
                  unsigned long, start, vki_size_t, length, int, advice);
 }
 
-PRE(sys_mremap, Special)
+PRE(sys_mremap)
 {
    // Nb: this is different to the glibc version described in the man pages,
    // which lacks the fifth 'new_address' argument.
@@ -2103,153 +2014,155 @@
                  unsigned long, old_addr, unsigned long, old_size,
                  unsigned long, new_size, unsigned long, flags,
                  unsigned long, new_addr);
-   SET_RESULT( mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) );
+   SET_STATUS_from_SysRes( 
+      mremap_segment((Addr)ARG1, ARG2, (Addr)ARG5, ARG3, ARG4, tid) 
+   );
 }
 
-PRE(sys_nice, 0)
-{
-   PRINT("sys_nice ( %d )", ARG1);
-   PRE_REG_READ1(long, "nice", int, inc);
-}
+//zz PRE(sys_nice, 0)
+//zz {
+//zz    PRINT("sys_nice ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "nice", int, inc);
+//zz }
+//zz 
+//zz PRE(sys_sched_getscheduler, 0)
+//zz {
+//zz    PRINT("sys_sched_getscheduler ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
+//zz }
+//zz 
+//zz PRE(sys_sched_setscheduler, 0)
+//zz {
+//zz    PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "sched_setscheduler", 
+//zz                  vki_pid_t, pid, int, policy, struct sched_param *, p);
+//zz    if (ARG3 != 0)
+//zz       PRE_MEM_READ( "sched_setscheduler(p)", 
+//zz 		    ARG3, sizeof(struct vki_sched_param));
+//zz }
+//zz 
+//zz PRE(sys_mlock, SfMayBlock)
+//zz {
+//zz    PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
+//zz    PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
+//zz }
+//zz 
+//zz PRE(sys_munlock, SfMayBlock)
+//zz {
+//zz    PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
+//zz    PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
+//zz }
+//zz 
+//zz PRE(sys_mlockall, SfMayBlock)
+//zz {
+//zz    PRINT("sys_mlockall ( %x )", ARG1);
+//zz    PRE_REG_READ1(long, "mlockall", int, flags);
+//zz }
+//zz 
+//zz PRE(sys_munlockall, SfMayBlock)
+//zz {
+//zz    PRINT("sys_munlockall ( )");
+//zz    PRE_REG_READ0(long, "munlockall");
+//zz }
+//zz 
+//zz PRE(sys_sched_get_priority_max, 0)
+//zz {
+//zz    PRINT("sched_get_priority_max ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
+//zz }
+//zz 
+//zz PRE(sys_sched_get_priority_min, 0)
+//zz {
+//zz    PRINT("sched_get_priority_min ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
+//zz }
+//zz 
+//zz PRE(sys_setpriority, 0)
+//zz {
+//zz    PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
+//zz }
+//zz 
+//zz PRE(sys_getpriority, 0)
+//zz {
+//zz    PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "getpriority", int, which, int, who);
+//zz }
+//zz 
+//zz PRE(sys_setregid16, 0)
+//zz {
+//zz    PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
+//zz }
+//zz 
+//zz // XXX: only for 32-bit archs
+//zz PRE(sys_pwrite64, SfMayBlock)
+//zz {
+//zz    PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
+//zz          ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
+//zz    PRE_REG_READ5(ssize_t, "pwrite64",
+//zz                  unsigned int, fd, const char *, buf, vki_size_t, count,
+//zz                  vki_u32, offset_low32, vki_u32, offset_high32);
+//zz    PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
+//zz }
+//zz 
+//zz PRE(sys_sync, SfMayBlock)
+//zz {
+//zz    PRINT("sys_sync ( )");
+//zz    PRE_REG_READ0(long, "sync");
+//zz }
+//zz 
+//zz PRE(sys_fstatfs, 0)
+//zz {
+//zz    PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "fstatfs",
+//zz                  unsigned int, fd, struct statfs *, buf);
+//zz    PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz 
+//zz POST(sys_fstatfs)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz 
+//zz PRE(sys_fstatfs64, 0)
+//zz {
+//zz    PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "fstatfs64",
+//zz                  unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
+//zz    PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
+//zz }
+//zz 
+//zz POST(sys_fstatfs64)
+//zz {
+//zz    POST_MEM_WRITE( ARG3, ARG2 );
+//zz }
+//zz 
+//zz PRE(sys_getsid, 0)
+//zz {
+//zz    PRINT("sys_getsid ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
+//zz }
+//zz 
+//zz // XXX: only for 32-bit archs
+//zz PRE(sys_pread64, SfMayBlock)
+//zz {
+//zz    PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
+//zz          ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
+//zz    PRE_REG_READ5(ssize_t, "pread64",
+//zz                  unsigned int, fd, char *, buf, vki_size_t, count,
+//zz                  vki_u32, offset_low32, vki_u32, offset_high32);
+//zz    PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
+//zz }
+//zz 
+//zz POST(sys_pread64)
+//zz {
+//zz    if (RES > 0) {
+//zz       POST_MEM_WRITE( ARG2, RES );
+//zz    }
+//zz }
 
-PRE(sys_sched_getscheduler, 0)
-{
-   PRINT("sys_sched_getscheduler ( %d )", ARG1);
-   PRE_REG_READ1(long, "sched_getscheduler", vki_pid_t, pid);
-}
-
-PRE(sys_sched_setscheduler, 0)
-{
-   PRINT("sys_sched_setscheduler ( %d, %d, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "sched_setscheduler", 
-                 vki_pid_t, pid, int, policy, struct sched_param *, p);
-   if (ARG3 != 0)
-      PRE_MEM_READ( "sched_setscheduler(p)", 
-		    ARG3, sizeof(struct vki_sched_param));
-}
-
-PRE(sys_mlock, MayBlock)
-{
-   PRINT("sys_mlock ( %p, %llu )", ARG1, (ULong)ARG2);
-   PRE_REG_READ2(long, "mlock", unsigned long, addr, vki_size_t, len);
-}
-
-PRE(sys_munlock, MayBlock)
-{
-   PRINT("sys_munlock ( %p, %llu )", ARG1, (ULong)ARG2);
-   PRE_REG_READ2(long, "munlock", unsigned long, addr, vki_size_t, len);
-}
-
-PRE(sys_mlockall, MayBlock)
-{
-   PRINT("sys_mlockall ( %x )", ARG1);
-   PRE_REG_READ1(long, "mlockall", int, flags);
-}
-
-PRE(sys_munlockall, MayBlock)
-{
-   PRINT("sys_munlockall ( )");
-   PRE_REG_READ0(long, "munlockall");
-}
-
-PRE(sys_sched_get_priority_max, 0)
-{
-   PRINT("sched_get_priority_max ( %d )", ARG1);
-   PRE_REG_READ1(long, "sched_get_priority_max", int, policy);
-}
-
-PRE(sys_sched_get_priority_min, 0)
-{
-   PRINT("sched_get_priority_min ( %d )", ARG1);
-   PRE_REG_READ1(long, "sched_get_priority_min", int, policy);
-}
-
-PRE(sys_setpriority, 0)
-{
-   PRINT("sys_setpriority ( %d, %d, %d )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "setpriority", int, which, int, who, int, prio);
-}
-
-PRE(sys_getpriority, 0)
-{
-   PRINT("sys_getpriority ( %d, %d )", ARG1, ARG2);
-   PRE_REG_READ2(long, "getpriority", int, which, int, who);
-}
-
-PRE(sys_setregid16, 0)
-{
-   PRINT("sys_setregid16 ( %d, %d )", ARG1, ARG2);
-   PRE_REG_READ2(long, "setregid16", vki_old_gid_t, rgid, vki_old_gid_t, egid);
-}
-
-// XXX: only for 32-bit archs
-PRE(sys_pwrite64, MayBlock)
-{
-   PRINT("sys_pwrite64 ( %d, %p, %llu, %lld )",
-         ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
-   PRE_REG_READ5(ssize_t, "pwrite64",
-                 unsigned int, fd, const char *, buf, vki_size_t, count,
-                 vki_u32, offset_low32, vki_u32, offset_high32);
-   PRE_MEM_READ( "pwrite64(buf)", ARG2, ARG3 );
-}
-
-PRE(sys_sync, MayBlock)
-{
-   PRINT("sys_sync ( )");
-   PRE_REG_READ0(long, "sync");
-}
-
-PRE(sys_fstatfs, 0)
-{
-   PRINT("sys_fstatfs ( %d, %p )",ARG1,ARG2);
-   PRE_REG_READ2(long, "fstatfs",
-                 unsigned int, fd, struct statfs *, buf);
-   PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct vki_statfs) );
-}
-
-POST(sys_fstatfs)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
-}
-
-PRE(sys_fstatfs64, 0)
-{
-   PRINT("sys_fstatfs64 ( %d, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
-   PRE_REG_READ3(long, "fstatfs64",
-                 unsigned int, fd, vki_size_t, size, struct statfs64 *, buf);
-   PRE_MEM_WRITE( "fstatfs64(buf)", ARG3, ARG2 );
-}
-
-POST(sys_fstatfs64)
-{
-   POST_MEM_WRITE( ARG3, ARG2 );
-}
-
-PRE(sys_getsid, 0)
-{
-   PRINT("sys_getsid ( %d )", ARG1);
-   PRE_REG_READ1(long, "getsid", vki_pid_t, pid);
-}
-
-// XXX: only for 32-bit archs
-PRE(sys_pread64, MayBlock)
-{
-   PRINT("sys_pread64 ( %d, %p, %llu, %lld )",
-         ARG1, ARG2, (ULong)ARG3, LOHI64(ARG4,ARG5));
-   PRE_REG_READ5(ssize_t, "pread64",
-                 unsigned int, fd, char *, buf, vki_size_t, count,
-                 vki_u32, offset_low32, vki_u32, offset_high32);
-   PRE_MEM_WRITE( "pread64(buf)", ARG2, ARG3 );
-}
-
-POST(sys_pread64)
-{
-   if (RES > 0) {
-      POST_MEM_WRITE( ARG2, RES );
-   }
-}
-
-PRE(sys_mknod, 0)
+PRE(sys_mknod)
 {
    PRINT("sys_mknod ( %p, 0x%x, 0x%x )", ARG1, ARG2, ARG3 );
    PRE_REG_READ3(long, "mknod",
@@ -2257,49 +2170,49 @@
    PRE_MEM_RASCIIZ( "mknod(pathname)", ARG1 );
 }
 
-PRE(sys_flock, MayBlock)
-{
-   PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
-   PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
-}
-
-PRE(sys_init_module, MayBlock)
-{
-   PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
-   PRE_REG_READ3(long, "init_module",
-                 void *, umod, unsigned long, len, const char *, uargs);
-   PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
-   PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
-}
-
-PRE(sys_capget, 0)
-{
-   PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
-   PRE_REG_READ2(long, "capget", 
-                 vki_cap_user_header_t, header, vki_cap_user_data_t, data);
-   PRE_MEM_READ( "capget(header)", ARG1, 
-                  sizeof(struct __vki_user_cap_header_struct) );
-   PRE_MEM_WRITE( "capget(data)", ARG2, 
-                  sizeof(struct __vki_user_cap_data_struct) );
-}
-
-POST(sys_capget)
-{
-   if (ARG2 != (Addr)NULL)
-      POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
-}
-
-PRE(sys_capset, 0)
-{
-   PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
-   PRE_REG_READ2(long, "capset", 
-                 vki_cap_user_header_t, header,
-                 const vki_cap_user_data_t, data);
-   PRE_MEM_READ( "capset(header)", 
-                  ARG1, sizeof(struct __vki_user_cap_header_struct) );
-   PRE_MEM_READ( "capset(data)", 
-                  ARG2, sizeof(struct __vki_user_cap_data_struct) );
-}
+//zz PRE(sys_flock, SfMayBlock)
+//zz {
+//zz    PRINT("sys_flock ( %d, %d )", ARG1, ARG2 );
+//zz    PRE_REG_READ2(long, "flock", unsigned int, fd, unsigned int, operation);
+//zz }
+//zz 
+//zz PRE(sys_init_module, SfMayBlock)
+//zz {
+//zz    PRINT("sys_init_module ( %p, %llu, %p )", ARG1, (ULong)ARG2, ARG3 );
+//zz    PRE_REG_READ3(long, "init_module",
+//zz                  void *, umod, unsigned long, len, const char *, uargs);
+//zz    PRE_MEM_READ( "init_module(umod)", ARG1, ARG2 );
+//zz    PRE_MEM_RASCIIZ( "init_module(uargs)", ARG3 );
+//zz }
+//zz 
+//zz PRE(sys_capget, 0)
+//zz {
+//zz    PRINT("sys_capget ( %p, %p )", ARG1, ARG2 );
+//zz    PRE_REG_READ2(long, "capget", 
+//zz                  vki_cap_user_header_t, header, vki_cap_user_data_t, data);
+//zz    PRE_MEM_READ( "capget(header)", ARG1, 
+//zz                   sizeof(struct __vki_user_cap_header_struct) );
+//zz    PRE_MEM_WRITE( "capget(data)", ARG2, 
+//zz                   sizeof(struct __vki_user_cap_data_struct) );
+//zz }
+//zz 
+//zz POST(sys_capget)
+//zz {
+//zz    if (ARG2 != (Addr)NULL)
+//zz       POST_MEM_WRITE( ARG2, sizeof(struct __vki_user_cap_data_struct) );
+//zz }
+//zz 
+//zz PRE(sys_capset, 0)
+//zz {
+//zz    PRINT("sys_capset ( %p, %p )", ARG1, ARG2 );
+//zz    PRE_REG_READ2(long, "capset", 
+//zz                  vki_cap_user_header_t, header,
+//zz                  const vki_cap_user_data_t, data);
+//zz    PRE_MEM_READ( "capset(header)", 
+//zz                   ARG1, sizeof(struct __vki_user_cap_header_struct) );
+//zz    PRE_MEM_READ( "capset(data)", 
+//zz                   ARG2, sizeof(struct __vki_user_cap_data_struct) );
+//zz }
 
 // Pre_read a char** argument.
 static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
@@ -2318,9 +2231,10 @@
 
 // XXX: prototype here seemingly doesn't match the prototype for i386-linux,
 // but it seems to work nonetheless...
-PRE(sys_execve, Special)
+PRE(sys_execve)
 {
-   Char *path;          /* path to executable */
+   Char*        path;          /* path to executable */
+   ThreadState* tst;
 
    PRINT("sys_execve ( %p(%s), %p, %p )", ARG1, ARG1, ARG2, ARG3);
    PRE_REG_READ3(vki_off_t, "execve",
@@ -2333,6 +2247,9 @@
 
    path = (Char *)ARG1;
 
+   vg_assert(VG_(is_valid_tid)(tid));
+   tst = VG_(get_ThreadState)(tid);
+
    /* Erk.  If the exec fails, then the following will have made a
       mess of things which makes it hard for us to continue.  The
       right thing to do is piece everything together again in
@@ -2341,17 +2258,18 @@
       exec. */
    {
       struct vki_stat st;
-      Int ret = VG_(stat)((Char *)ARG1, &st);
+      Int i = VG_(stat)((Char *)ARG1, &st);
 
-      if (ret < 0) {
-	 SET_RESULT( ret );
+      if (i == -1) {
+         /* stat failed */
+         SET_STATUS_Failure( VKI_EACCES/*really, we should copy stat's result*/ );
 	 return;
       }
       /* just look for regular file with any X bit set
 	 XXX do proper permissions check?
        */
       if ((st.st_mode & 0100111) == 0100000) {
-	 SET_RESULT( -VKI_EACCES );
+	 SET_STATUS_Failure( VKI_EACCES );
 	 return;
       }
    }
@@ -2439,7 +2357,9 @@
       VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
    }
 
-   SET_RESULT( VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3) );
+   SET_STATUS_from_SysRes( 
+      VG_(do_syscall3)(__NR_execve, (UWord)path, ARG2, ARG3) 
+   );
 
    /* If we got here, then the execve failed.  We've already made too
       much of a mess of ourselves to continue, so we have to abort. */
@@ -2447,27 +2367,28 @@
                 ARG1, ARG1, ARG2, ARG3, -RES);
    VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
                             "execve() failing, so I'm dying.");
-   VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(execve), "
+   VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
                             "or work out how to recover.");
    VG_(exit)(101);
 }
 
-PRE(sys_access, 0)
+PRE(sys_access)
 {
    PRINT("sys_access ( %p(%s), %d )", ARG1,ARG1,ARG2);
    PRE_REG_READ2(long, "access", const char *, pathname, int, mode);
    PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
 }
 
-PRE(sys_alarm, 0)
+PRE(sys_alarm)
 {
    PRINT("sys_alarm ( %d )", ARG1);
    PRE_REG_READ1(unsigned long, "alarm", unsigned int, seconds);
 }
 
-PRE(sys_brk, Special)
+PRE(sys_brk)
 {
    Addr brk_limit = VG_(brk_limit);
+   Addr brk_new; 
 
    /* libc   says: int   brk(void *end_data_segment);
       kernel says: void* brk(void* end_data_segment);  (more or less)
@@ -2487,74 +2408,75 @@
    PRINT("sys_brk ( %p )", ARG1);
    PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
 
-   SET_RESULT( do_brk(ARG1) );
+   brk_new = do_brk(ARG1);
+   SET_STATUS_Success( brk_new );
 
-   if (RES == ARG1) {
+   if (brk_new == ARG1) {
       /* brk() succeeded */
-      if (RES < brk_limit) {
+      if (brk_new < brk_limit) {
          /* successfully shrunk the data segment. */
          VG_TRACK( die_mem_brk, (Addr)ARG1,
 		   brk_limit-ARG1 );
       } else
-      if (RES > brk_limit) {
+      if (brk_new > brk_limit) {
          /* successfully grew the data segment */
          VG_TRACK( new_mem_brk, brk_limit,
                                 ARG1-brk_limit );
       }
    } else {
       /* brk() failed */
-      vg_assert(brk_limit == RES);
+      vg_assert(brk_limit == brk_new);
    }
 }
 
-PRE(sys_chdir, 0)
+PRE(sys_chdir)
 {
    PRINT("sys_chdir ( %p )", ARG1);
    PRE_REG_READ1(long, "chdir", const char *, path);
    PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
 }
 
-PRE(sys_chmod, 0)
+PRE(sys_chmod)
 {
    PRINT("sys_chmod ( %p, %d )", ARG1,ARG2);
    PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode);
    PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
 }
 
-PRE(sys_chown16, 0)
-{
-   PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "chown16",
-                 const char *, path,
-                 vki_old_uid_t, owner, vki_old_gid_t, group);
-   PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
-}
+//zz PRE(sys_chown16, 0)
+//zz {
+//zz    PRINT("sys_chown16 ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "chown16",
+//zz                  const char *, path,
+//zz                  vki_old_uid_t, owner, vki_old_gid_t, group);
+//zz    PRE_MEM_RASCIIZ( "chown16(path)", ARG1 );
+//zz }
+//zz 
+//zz PRE(sys_chown, 0)
+//zz {
+//zz    /* int chown(const char *path, uid_t owner, gid_t group); */
+//zz    PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "chown",
+//zz                  const char *, path, vki_uid_t, owner, vki_gid_t, group);
+//zz    PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
+//zz }
+//zz 
+//zz PRE(sys_lchown, 0)
+//zz {
+//zz    PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "lchown",
+//zz                  const char *, path, vki_uid_t, owner, vki_gid_t, group);
+//zz    PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
+//zz }
 
-PRE(sys_chown, 0)
-{
-   /* int chown(const char *path, uid_t owner, gid_t group); */
-   PRINT("sys_chown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "chown",
-                 const char *, path, vki_uid_t, owner, vki_gid_t, group);
-   PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
-}
-
-PRE(sys_lchown, 0)
-{
-   PRINT("sys_lchown ( %p, 0x%x, 0x%x )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "lchown",
-                 const char *, path, vki_uid_t, owner, vki_gid_t, group);
-   PRE_MEM_RASCIIZ( "lchown(path)", ARG1 );
-}
-
-PRE(sys_close, 0)
+PRE(sys_close)
 {
    PRINT("sys_close ( %d )", ARG1);
    PRE_REG_READ1(long, "close", unsigned int, fd);
 
    /* Detect and negate attempts by the client to close Valgrind's log fd */
    if (!VG_(fd_allowed)(ARG1, "close", tid, False))
-      SET_RESULT( -VKI_EBADF );
+      SET_STATUS_Failure( VKI_EBADF );
 }
 
 POST(sys_close)
@@ -2562,7 +2484,7 @@
    if (VG_(clo_track_fds)) record_fd_close(tid, ARG1);
 }
 
-PRE(sys_dup, 0)
+PRE(sys_dup)
 {
    PRINT("sys_dup ( %d )", ARG1);
    PRE_REG_READ1(long, "dup", unsigned int, oldfd);
@@ -2570,117 +2492,119 @@
 
 POST(sys_dup)
 {
+   vg_assert(SUCCESS);
    if (!VG_(fd_allowed)(RES, "dup", tid, True)) {
       VG_(close)(RES);
-      SET_RESULT( -VKI_EMFILE );
+      SET_STATUS_Failure( VKI_EMFILE );
    } else {
       if (VG_(clo_track_fds))
          VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
    }
 }
 
-PRE(sys_dup2, 0)
+PRE(sys_dup2)
 {
    PRINT("sys_dup2 ( %d, %d )", ARG1,ARG2);
    PRE_REG_READ2(long, "dup2", unsigned int, oldfd, unsigned int, newfd);
    if (!VG_(fd_allowed)(ARG2, "dup2", tid, True))
-      SET_RESULT( -VKI_EBADF );
+      SET_STATUS_Failure( VKI_EBADF );
 }
 
 POST(sys_dup2)
 {
+   vg_assert(SUCCESS);
    if (VG_(clo_track_fds))
       VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
 }
 
-PRE(sys_fchdir, 0)
-{
-   PRINT("sys_fchdir ( %d )", ARG1);
-   PRE_REG_READ1(long, "fchdir", unsigned int, fd);
-}
-
-PRE(sys_fchown16, 0)
-{
-   PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "fchown16",
-                 unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
-}
-
-PRE(sys_fchown, 0)
-{
-   PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "fchown",
-                 unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
-}
-
-PRE(sys_fchmod, 0)
-{
-   PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
-   PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
-}
-
-PRE(sys_fcntl, 0)
-{
-   switch (ARG2) {
-   // These ones ignore ARG3.
-   case VKI_F_GETFD:
-   case VKI_F_GETFL:
-   case VKI_F_GETOWN:
-   case VKI_F_SETOWN:
-   case VKI_F_GETSIG:
-   case VKI_F_SETSIG:
-   case VKI_F_GETLEASE:
-      PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
-      PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
-      break;
-
-   // These ones use ARG3 as "arg".
-   case VKI_F_DUPFD:
-   case VKI_F_SETFD:
-   case VKI_F_SETFL:
-   case VKI_F_SETLEASE:
-   case VKI_F_NOTIFY:
-      PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
-      PRE_REG_READ3(long, "fcntl",
-                    unsigned int, fd, unsigned int, cmd, unsigned long, arg);
-      break;
-
-   // These ones use ARG3 as "lock".
-   case VKI_F_GETLK:
-   case VKI_F_SETLK:
-   case VKI_F_SETLKW:
-#ifndef __amd64__
-   case VKI_F_GETLK64:
-   case VKI_F_SETLK64:
-   case VKI_F_SETLKW64:
-#else
-#endif
-      PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
-      PRE_REG_READ3(long, "fcntl",
-                    unsigned int, fd, unsigned int, cmd,
-                    struct flock64 *, lock);
-      break;
-   }
-
-   //if (ARG2 == VKI_F_SETLKW)
-   //   tst->sys_flags |= MayBlock;
-}
-
-POST(sys_fcntl)
-{
-   if (ARG2 == VKI_F_DUPFD) {
-      if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
-         VG_(close)(RES);
-         SET_RESULT( -VKI_EMFILE );
-      } else {
-         if (VG_(clo_track_fds))
-            VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
-      }
-   }
-}
+//zz PRE(sys_fchdir, 0)
+//zz {
+//zz    PRINT("sys_fchdir ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "fchdir", unsigned int, fd);
+//zz }
+//zz 
+//zz PRE(sys_fchown16, 0)
+//zz {
+//zz    PRINT("sys_fchown16 ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "fchown16",
+//zz                  unsigned int, fd, vki_old_uid_t, owner, vki_old_gid_t, group);
+//zz }
+//zz 
+//zz PRE(sys_fchown, 0)
+//zz {
+//zz    PRINT("sys_fchown ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "fchown",
+//zz                  unsigned int, fd, vki_uid_t, owner, vki_gid_t, group);
+//zz }
+//zz 
+//zz PRE(sys_fchmod, 0)
+//zz {
+//zz    PRINT("sys_fchmod ( %d, %d )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode);
+//zz }
+//zz 
+//zz PRE(sys_fcntl, 0)
+//zz {
+//zz    switch (ARG2) {
+//zz    // These ones ignore ARG3.
+//zz    case VKI_F_GETFD:
+//zz    case VKI_F_GETFL:
+//zz    case VKI_F_GETOWN:
+//zz    case VKI_F_SETOWN:
+//zz    case VKI_F_GETSIG:
+//zz    case VKI_F_SETSIG:
+//zz    case VKI_F_GETLEASE:
+//zz       PRINT("sys_fcntl ( %d, %d )", ARG1,ARG2);
+//zz       PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
+//zz       break;
+//zz 
+//zz    // These ones use ARG3 as "arg".
+//zz    case VKI_F_DUPFD:
+//zz    case VKI_F_SETFD:
+//zz    case VKI_F_SETFL:
+//zz    case VKI_F_SETLEASE:
+//zz    case VKI_F_NOTIFY:
+//zz       PRINT("sys_fcntl[ARG3=='arg'] ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz       PRE_REG_READ3(long, "fcntl",
+//zz                     unsigned int, fd, unsigned int, cmd, unsigned long, arg);
+//zz       break;
+//zz 
+//zz    // These ones use ARG3 as "lock".
+//zz    case VKI_F_GETLK:
+//zz    case VKI_F_SETLK:
+//zz    case VKI_F_SETLKW:
+//zz #ifndef __amd64__
+//zz    case VKI_F_GETLK64:
+//zz    case VKI_F_SETLK64:
+//zz    case VKI_F_SETLKW64:
+//zz #else
+//zz #endif
+//zz       PRINT("sys_fcntl[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
+//zz       PRE_REG_READ3(long, "fcntl",
+//zz                     unsigned int, fd, unsigned int, cmd,
+//zz                     struct flock64 *, lock);
+//zz       break;
+//zz    }
+//zz 
+//zz    //if (ARG2 == VKI_F_SETLKW)
+//zz    //   tst->sys_flags |= SfMayBlock;
+//zz }
+//zz 
+//zz POST(sys_fcntl)
+//zz {
+//zz    if (ARG2 == VKI_F_DUPFD) {
+//zz       if (!VG_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
+//zz          VG_(close)(RES);
+//zz          SET_STATUS_( -VKI_EMFILE );
+//zz       } else {
+//zz          if (VG_(clo_track_fds))
+//zz             VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+//zz       }
+//zz    }
+//zz }
 
 // XXX: wrapper only suitable for 32-bit systems
-PRE(sys_fcntl64, 0)
+PRE(sys_fcntl64)
 {
    switch (ARG2) {
    // These ones ignore ARG3.
@@ -2710,11 +2634,11 @@
    case VKI_F_GETLK:
    case VKI_F_SETLK:
    case VKI_F_SETLKW:
-#ifndef __amd64__
+#  if defined(VGP_amd64_linux)
    case VKI_F_GETLK64:
    case VKI_F_SETLK64:
    case VKI_F_SETLKW64:
-#endif
+#  endif
       PRINT("sys_fcntl64[ARG3=='lock'] ( %d, %d, %p )", ARG1,ARG2,ARG3);
       PRE_REG_READ3(long, "fcntl64",
                     unsigned int, fd, unsigned int, cmd,
@@ -2722,45 +2646,47 @@
       break;
    }
    
-#ifndef __amd64__
+#  if defined(VGP_amd64_linux)
    //if (ARG2 == VKI_F_SETLKW || ARG2 == VKI_F_SETLKW64)
-   //   tst->sys_flags |= MayBlock;
-#else
+   //   tst->sys_flags |= SfMayBlock;
+#  else
    //if (ARG2 == VKI_F_SETLKW)
-   //   tst->sys_flags |= MayBlock;
-#endif
+   //   tst->sys_flags |= SfMayBlock;
+#  endif
 }
 
 POST(sys_fcntl64)
 {
+   vg_assert(SUCCESS);
    if (ARG2 == VKI_F_DUPFD) {
       if (!VG_(fd_allowed)(RES, "fcntl64(DUPFD)", tid, True)) {
          VG_(close)(RES);
-         SET_RESULT( -VKI_EMFILE );
+         SET_STATUS_Failure( VKI_EMFILE );
       } else {
          if (VG_(clo_track_fds))
-            VG_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+            VG_(record_fd_open)(tid, RES, 
+                                VG_(resolve_filename)(RES));
       }
    }
 }
 
-PRE(sys_newfstat, 0)
-{
-   PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
-   PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
-}
-
-POST(sys_newfstat)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
-}
+//zz PRE(sys_newfstat, 0)
+//zz {
+//zz    PRINT("sys_newfstat ( %d, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf);
+//zz    PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz 
+//zz POST(sys_newfstat)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
+//zz }
 
 static vki_sigset_t fork_saved_mask;
 
 // In Linux, the sys_fork() function varies across architectures, but we
 // ignore the various args it gets, and so it looks arch-neutral.  Hmm.
-PRE(sys_fork, 0)
+PRE(sys_fork)
 {
    vki_sigset_t mask;
 
@@ -2774,14 +2700,16 @@
 
    VG_(do_atfork_pre)(tid);
 
-   SET_RESULT(VG_(do_syscall0)(__NR_fork));
+   SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
 
-   if (RES == 0) {
+   if (SUCCESS && RES == 0) {
       VG_(do_atfork_child)(tid);
 
       /* restore signal mask */
       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   } else if (RES > 0) {
+   } 
+   else 
+   if (SUCCESS && RES > 0) {
       PRINT("   fork: process %d created child %d\n", VG_(getpid)(), RES);
 
       VG_(do_atfork_parent)(tid);
@@ -2791,57 +2719,58 @@
    }
 }
 
-PRE(sys_ftruncate, MayBlock)
-{
-   PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
-   PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
-}
+//zz PRE(sys_ftruncate, SfMayBlock)
+//zz {
+//zz    PRINT("sys_ftruncate ( %d, %lld )", ARG1,(ULong)ARG2);
+//zz    PRE_REG_READ2(long, "ftruncate", unsigned int, fd, unsigned long, length);
+//zz }
+//zz 
+//zz PRE(sys_truncate, SfMayBlock)
+//zz {
+//zz    PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "truncate", 
+//zz                  const char *, path, unsigned long, length);
+//zz    PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
+//zz }
+//zz 
+//zz // XXX: this wrapper is only suitable for 32-bit platforms
+//zz PRE(sys_ftruncate64, SfMayBlock)
+//zz {
+//zz    PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
+//zz    PRE_REG_READ3(long, "ftruncate64",
+//zz                  unsigned int, fd,
+//zz                  vki_u32, length_low32, vki_u32, length_high32);
+//zz }
+//zz 
+//zz // XXX: this wrapper is only suitable for 32-bit platforms
+//zz PRE(sys_truncate64, SfMayBlock)
+//zz {
+//zz    PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
+//zz    PRE_REG_READ3(long, "truncate64",
+//zz                  const char *, path,
+//zz                  vki_u32, length_low32, vki_u32, length_high32);
+//zz    PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
+//zz }
+//zz 
+//zz 
+//zz PRE(sys_getdents, SfMayBlock)
+//zz {
+//zz    PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "getdents",
+//zz                  unsigned int, fd, struct linux_dirent *, dirp,
+//zz                  unsigned int, count);
+//zz    PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
+//zz }
+//zz 
+//zz POST(sys_getdents)
+//zz {
+//zz    if (RES > 0)
+//zz       POST_MEM_WRITE( ARG2, RES );
+//zz }
 
-PRE(sys_truncate, MayBlock)
+PRE(sys_getdents64)
 {
-   PRINT("sys_truncate ( %p(%s), %d )", ARG1,ARG1,ARG2);
-   PRE_REG_READ2(long, "truncate", 
-                 const char *, path, unsigned long, length);
-   PRE_MEM_RASCIIZ( "truncate(path)", ARG1 );
-}
-
-// XXX: this wrapper is only suitable for 32-bit platforms
-PRE(sys_ftruncate64, MayBlock)
-{
-   PRINT("sys_ftruncate64 ( %d, %lld )", ARG1, LOHI64(ARG2,ARG3));
-   PRE_REG_READ3(long, "ftruncate64",
-                 unsigned int, fd,
-                 vki_u32, length_low32, vki_u32, length_high32);
-}
-
-// XXX: this wrapper is only suitable for 32-bit platforms
-PRE(sys_truncate64, MayBlock)
-{
-   PRINT("sys_truncate64 ( %p, %lld )", ARG1, LOHI64(ARG2, ARG3));
-   PRE_REG_READ3(long, "truncate64",
-                 const char *, path,
-                 vki_u32, length_low32, vki_u32, length_high32);
-   PRE_MEM_RASCIIZ( "truncate64(path)", ARG1 );
-}
-
-
-PRE(sys_getdents, MayBlock)
-{
-   PRINT("sys_getdents ( %d, %p, %d )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "getdents",
-                 unsigned int, fd, struct linux_dirent *, dirp,
-                 unsigned int, count);
-   PRE_MEM_WRITE( "getdents(dirp)", ARG2, ARG3 );
-}
-
-POST(sys_getdents)
-{
-   if (RES > 0)
-      POST_MEM_WRITE( ARG2, RES );
-}
-
-PRE(sys_getdents64, MayBlock)
-{
+  *flags |= SfMayBlock;
    PRINT("sys_getdents64 ( %d, %p, %d )",ARG1,ARG2,ARG3);
    PRE_REG_READ3(long, "getdents64",
                  unsigned int, fd, struct linux_dirent64 *, dirp,
@@ -2851,39 +2780,40 @@
 
 POST(sys_getdents64)
 {
+   vg_assert(SUCCESS);
    if (RES > 0)
       POST_MEM_WRITE( ARG2, RES );
 }
 
-PRE(sys_getgroups16, 0)
-{
-   PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
-   PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
-   if (ARG1 > 0)
-      PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
-}
+//zz PRE(sys_getgroups16, 0)
+//zz {
+//zz    PRINT("sys_getgroups16 ( %d, %p )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "getgroups16", int, size, vki_old_gid_t *, list);
+//zz    if (ARG1 > 0)
+//zz       PRE_MEM_WRITE( "getgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
+//zz }
+//zz 
+//zz POST(sys_getgroups16)
+//zz {
+//zz    if (ARG1 > 0 && RES > 0)
+//zz       POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
+//zz }
+//zz 
+//zz PRE(sys_getgroups, 0)
+//zz {
+//zz    PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
+//zz    if (ARG1 > 0)
+//zz       PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
+//zz }
+//zz 
+//zz POST(sys_getgroups)
+//zz {
+//zz    if (ARG1 > 0 && RES > 0)
+//zz       POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
+//zz }
 
-POST(sys_getgroups16)
-{
-   if (ARG1 > 0 && RES > 0)
-      POST_MEM_WRITE( ARG2, RES * sizeof(vki_old_gid_t) );
-}
-
-PRE(sys_getgroups, 0)
-{
-   PRINT("sys_getgroups ( %d, %p )", ARG1, ARG2);
-   PRE_REG_READ2(long, "getgroups", int, size, vki_gid_t *, list);
-   if (ARG1 > 0)
-      PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
-}
-
-POST(sys_getgroups)
-{
-   if (ARG1 > 0 && RES > 0)
-      POST_MEM_WRITE( ARG2, RES * sizeof(vki_gid_t) );
-}
-
-PRE(sys_getcwd, 0)
+PRE(sys_getcwd)
 {
    // Note that the kernel version of getcwd() behaves quite differently to
    // the glibc one.
@@ -2894,65 +2824,66 @@
 
 POST(sys_getcwd)
 {
+   vg_assert(SUCCESS);
    if (RES != (Addr)NULL)
       POST_MEM_WRITE( ARG1, RES );
 }
 
-PRE(sys_geteuid16, 0)
+PRE(sys_geteuid16)
 {
    PRINT("sys_geteuid16 ( )");
    PRE_REG_READ0(long, "geteuid16");
 }
 
-PRE(sys_geteuid, 0)
+PRE(sys_geteuid)
 {
    PRINT("sys_geteuid ( )");
    PRE_REG_READ0(long, "geteuid");
 }
 
-PRE(sys_getegid16, 0)
-{
-   PRINT("sys_getegid16 ( )");
-   PRE_REG_READ0(long, "getegid16");
-}
+//zz PRE(sys_getegid16, 0)
+//zz {
+//zz    PRINT("sys_getegid16 ( )");
+//zz    PRE_REG_READ0(long, "getegid16");
+//zz }
+//zz 
+//zz PRE(sys_getegid, 0)
+//zz {
+//zz    PRINT("sys_getegid ( )");
+//zz    PRE_REG_READ0(long, "getegid");
+//zz }
+//zz 
+//zz PRE(sys_getgid16, 0)
+//zz {
+//zz    PRINT("sys_getgid16 ( )");
+//zz    PRE_REG_READ0(long, "getgid16");
+//zz }
+//zz 
+//zz PRE(sys_getgid, 0)
+//zz {
+//zz    PRINT("sys_getgid ( )");
+//zz    PRE_REG_READ0(long, "getgid");
+//zz }
 
-PRE(sys_getegid, 0)
-{
-   PRINT("sys_getegid ( )");
-   PRE_REG_READ0(long, "getegid");
-}
-
-PRE(sys_getgid16, 0)
-{
-   PRINT("sys_getgid16 ( )");
-   PRE_REG_READ0(long, "getgid16");
-}
-
-PRE(sys_getgid, 0)
-{
-   PRINT("sys_getgid ( )");
-   PRE_REG_READ0(long, "getgid");
-}
-
-PRE(sys_getpid, 0)
+PRE(sys_getpid)
 {
    PRINT("sys_getpid ()");
    PRE_REG_READ0(long, "getpid");
 }
 
-PRE(sys_getpgid, 0)
-{
-   PRINT("sys_getpgid ( %d )", ARG1);
-   PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
-}
+//zz PRE(sys_getpgid, 0)
+//zz {
+//zz    PRINT("sys_getpgid ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "getpgid", vki_pid_t, pid);
+//zz }
+//zz 
+//zz PRE(sys_getpgrp, 0)
+//zz {
+//zz    PRINT("sys_getpgrp ()");
+//zz    PRE_REG_READ0(long, "getpgrp");
+//zz }
 
-PRE(sys_getpgrp, 0)
-{
-   PRINT("sys_getpgrp ()");
-   PRE_REG_READ0(long, "getpgrp");
-}
-
-PRE(sys_getppid, 0)
+PRE(sys_getppid)
 {
    PRINT("sys_getppid ()");
    PRE_REG_READ0(long, "getppid");
@@ -2978,20 +2909,20 @@
     }
 }
 
-PRE(sys_old_getrlimit, 0)
-{
-   PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "old_getrlimit",
-                 unsigned int, resource, struct rlimit *, rlim);
-   PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
-}
+//zz PRE(sys_old_getrlimit, 0)
+//zz {
+//zz    PRINT("sys_old_getrlimit ( %d, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "old_getrlimit",
+//zz                  unsigned int, resource, struct rlimit *, rlim);
+//zz    PRE_MEM_WRITE( "old_getrlimit(rlim)", ARG2, sizeof(struct vki_rlimit) );
+//zz }
+//zz 
+//zz POST(sys_old_getrlimit)
+//zz {
+//zz    common_post_getrlimit(tid, ARG1, ARG2);
+//zz }
 
-POST(sys_old_getrlimit)
-{
-   common_post_getrlimit(tid, ARG1, ARG2);
-}
-
-PRE(sys_getrlimit, 0)
+PRE(sys_getrlimit)
 {
    PRINT("sys_getrlimit ( %d, %p )", ARG1,ARG2);
    PRE_REG_READ2(long, "getrlimit",
@@ -3004,21 +2935,21 @@
    common_post_getrlimit(tid, ARG1, ARG2);
 }
 
-PRE(sys_getrusage, 0)
-{
-   /* int getrusage (int who, struct rusage *usage); */
-   PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
-   PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
-}
+//zz PRE(sys_getrusage, 0)
+//zz {
+//zz    /* int getrusage (int who, struct rusage *usage); */
+//zz    PRINT("sys_getrusage ( %d, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "getrusage", int, who, struct rusage *, usage);
+//zz    PRE_MEM_WRITE( "getrusage(usage)", ARG2, sizeof(struct vki_rusage) );
+//zz }
+//zz 
+//zz POST(sys_getrusage)
+//zz {
+//zz    if (RES == 0)
+//zz       POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
+//zz }
 
-POST(sys_getrusage)
-{
-   if (RES == 0)
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_rusage) );
-}
-
-PRE(sys_gettimeofday, 0)
+PRE(sys_gettimeofday)
 {
    PRINT("sys_gettimeofday ( %p, %p )", ARG1,ARG2);
    PRE_REG_READ2(long, "gettimeofday",
@@ -3030,6 +2961,7 @@
 
 POST(sys_gettimeofday)
 {
+   vg_assert(SUCCESS);
    if (RES == 0) {
       POST_MEM_WRITE( ARG1, sizeof(struct vki_timeval) );
       if (ARG2 != 0)
@@ -3037,33 +2969,34 @@
    }
 }
 
-PRE(sys_settimeofday, 0)
-{
-   PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "settimeofday",
-                 struct timeval *, tv, struct timezone *, tz);
-   PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
-   if (ARG2 != 0) {
-      PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
-      /* maybe should warn if tz->tz_dsttime is non-zero? */
-   }
-}
+//zz PRE(sys_settimeofday, 0)
+//zz {
+//zz    PRINT("sys_settimeofday ( %p, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "settimeofday",
+//zz                  struct timeval *, tv, struct timezone *, tz);
+//zz    PRE_MEM_READ( "settimeofday(tv)", ARG1, sizeof(struct vki_timeval) );
+//zz    if (ARG2 != 0) {
+//zz       PRE_MEM_READ( "settimeofday(tz)", ARG2, sizeof(struct vki_timezone) );
+//zz       /* maybe should warn if tz->tz_dsttime is non-zero? */
+//zz    }
+//zz }
 
-PRE(sys_getuid16, 0)
+PRE(sys_getuid16)
 {
    PRINT("sys_getuid16 ( )");
    PRE_REG_READ0(long, "getuid16");
 }
 
-PRE(sys_getuid, 0)
+PRE(sys_getuid)
 {
    PRINT("sys_getuid ( )");
    PRE_REG_READ0(long, "getuid");
 }
 
 // XXX: I reckon some of these cases must be x86-specific
-PRE(sys_ioctl, MayBlock)
+PRE(sys_ioctl)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_ioctl ( %d, 0x%x, %p )",ARG1,ARG2,ARG3);
    PRE_REG_READ3(long, "ioctl",
                  unsigned int, fd, unsigned int, request, unsigned long, arg);
@@ -3378,7 +3311,7 @@
       break;
    case VKI_SIOCSPGRP:
       PRE_MEM_READ( "ioctl(SIOCSPGRP)", ARG3, sizeof(int) );
-      //tst->sys_flags &= ~MayBlock;
+      //tst->sys_flags &= ~SfMayBlock;
       break;
 
       /* linux/soundcard interface (OSS) */
@@ -3827,6 +3760,7 @@
 
 POST(sys_ioctl)
 {
+   vg_assert(SUCCESS);
    switch (ARG2 /* request */) {
    case VKI_TCSETS:
    case VKI_TCSETSW:
@@ -4323,7 +4257,7 @@
       UInt dir  = _VKI_IOC_DIR(ARG2);
       UInt size = _VKI_IOC_SIZE(ARG2);
       if (size > 0 && (dir & _VKI_IOC_READ)
-	  && RES == 0
+	  && RES == 0 
 	  && ARG3 != (Addr)NULL)
 	 POST_MEM_WRITE(ARG3, size);
       break;
@@ -4369,7 +4303,8 @@
    /* Check to see that the target isn't already exiting. */
    if (!VG_(is_exiting)(tid)) {
       if (VG_(clo_trace_signals))
-	 VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL", tst->tid);
+	 VG_(message)(Vg_DebugMsg, "Thread %d being killed with SIGKILL", 
+                                   tst->tid);
       
       tst->exitreason = VgSrc_FatalSig;
       tst->os_state.fatalsig = VKI_SIGKILL;
@@ -4381,167 +4316,74 @@
    return True;
 }
 
-PRE(sys_kill, Special)
+PRE(sys_kill)
 {
    /* int kill(pid_t pid, int sig); */
    PRINT("sys_kill ( %d, %d )", ARG1,ARG2);
    PRE_REG_READ2(long, "kill", int, pid, int, sig);
    if (!VG_(client_signal_OK)(ARG2)) {
-      SET_RESULT( -VKI_EINVAL );
+      SET_STATUS_Failure( VKI_EINVAL );
       return;
    }
 
    /* If we're sending SIGKILL, check to see if the target is one of
       our threads and handle it specially. */
    if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
-      SET_RESULT(0);
+      SET_STATUS_Success(0);
    else
-      SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
+      SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
 
    if (VG_(clo_trace_signals))
       VG_(message)(Vg_DebugMsg, "kill: sent signal %d to pid %d",
 		   ARG2, ARG1);
-   // Check to see if this kill gave us a pending signal
-   VG_(poll_signals)(tid);
+
+   /* This kill might have given us a pending signal.  Ask for a check once 
+      the syscall is done. */
+   *flags |= SfPollAfter;
 }
 
-PRE(sys_link, MayBlock)
+PRE(sys_link)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_link ( %p, %p)", ARG1, ARG2);
    PRE_REG_READ2(long, "link", const char *, oldpath, const char *, newpath);
    PRE_MEM_RASCIIZ( "link(oldpath)", ARG1);
    PRE_MEM_RASCIIZ( "link(newpath)", ARG2);
 }
 
-PRE(sys_lseek, 0)
+PRE(sys_lseek)
 {
    PRINT("sys_lseek ( %d, %d, %d )", ARG1,ARG2,ARG3);
    PRE_REG_READ3(vki_off_t, "lseek",
                  unsigned int, fd, vki_off_t, offset, unsigned int, whence);
 }
 
-PRE(sys_newlstat, 0)
-{
-   PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
-   PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
-   PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
-   PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
-}
+//zz PRE(sys_newlstat, 0)
+//zz {
+//zz    PRINT("sys_newlstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "lstat", char *, file_name, struct stat *, buf);
+//zz    PRE_MEM_RASCIIZ( "lstat(file_name)", ARG1 );
+//zz    PRE_MEM_WRITE( "lstat(buf)", ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz 
+//zz POST(sys_newlstat)
+//zz {
+//zz    if (RES == 0) {
+//zz       POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
+//zz    }
+//zz }
 
-POST(sys_newlstat)
+PRE(sys_mkdir)
 {
-   if (RES == 0) {
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
-   }
-}
-
-// XXX: this syscall is generic, but not necessarily applicable to every
-// architecture -- I think only to 32-bit archs.  We're going to need
-// something like linux/core_os32.h for such things, eventually, I think.
-// --njn
-#ifndef __amd64__
-PRE(sys_lstat64, 0)
-{
-   PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
-   PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
-   PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
-   PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
-}
-
-POST(sys_lstat64)
-{
-   if (RES == 0) {
-      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
-   }
-}
-#endif
-
-PRE(sys_mkdir, MayBlock)
-{
+   *flags |= SfMayBlock;
    PRINT("sys_mkdir ( %p, %d )", ARG1,ARG2);
    PRE_REG_READ2(long, "mkdir", const char *, pathname, int, mode);
    PRE_MEM_RASCIIZ( "mkdir(pathname)", ARG1 );
 }
 
-// Nb: this should probably be in m_syscalls/syscalls-x86-linux.c, but it
-// might be required for ARM, and I was too lazy to move it (which would
-// have required making mmap_segment() public).
-PRE(old_mmap, Special)
+PRE(sys_mmap2)
 {
-   /* struct mmap_arg_struct {           
-         unsigned long addr;
-         unsigned long len;
-         unsigned long prot;
-         unsigned long flags;
-         unsigned long fd;
-         unsigned long offset;
-   }; */
-#if defined(VGP_x86_linux)
-   // do nothing
-#else
-   vg_assert2(0, "old_mmap should only be called on x86/Linux");
-#endif
-   
-   UWord a1, a2, a3, a4, a5, a6;
-   UWord *arg_block = (UWord*)(tst->arch.vex.VGP_SYSCALL_ARG1);
-
-   PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
-   arg_block = (UWord*)(tst->arch.vex.VGP_SYSCALL_ARG1);
-   PRE_MEM_READ( "old_mmap(args)", (Addr)arg_block, 6*sizeof(UWord) );\
-   a1 = arg_block[0];
-   a2 = arg_block[1];
-   a3 = arg_block[2];
-   a4 = arg_block[3];
-   a5 = arg_block[4];
-   a6 = arg_block[5];
-
-   PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
-         a1, (ULong)a2, a3, a4, a5, a6 );
-
-   if (a2 == 0) {
-      /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
-         shall be established. */
-      SET_RESULT( -VKI_EINVAL );
-      return;
-   }
-
-   if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
-      /* zap any misaligned addresses. */
-      SET_RESULT( -VKI_EINVAL );
-      return;
-   }
-
-   if (a4 & VKI_MAP_FIXED) {
-      if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
-         PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
-         SET_RESULT( -VKI_ENOMEM );
-      }
-   } else {
-      Addr a = VG_(find_map_space)(a1, a2, True);
-      if (a == 0 && a1 != 0)
-         a1 = VG_(find_map_space)(0, a2, True);
-      else
-         a1 = a;
-      if (a1 == 0)
-         SET_RESULT( -VKI_ENOMEM );
-      else
-         a4 |= VKI_MAP_FIXED;
-   }
-
-   if (RES != -VKI_ENOMEM) {
-      Int res = (Int)VG_(mmap_native)((void*)a1, a2, a3, a4, a5, a6);
-      SET_RESULT(res);
-
-      if (!VG_(is_kerror)(RES)) {
-         vg_assert(VG_(valid_client_addr)(RES, a2, tid, "old_mmap"));
-         mmap_segment( (Addr)RES, a2, a3, a4, a5, a6 );
-      }
-   }
-}
-
-PRE(sys_mmap2, 0)
-{
-   // Exactly like old_mmap() except:
+   // Exactly like old_mmap() in x86-linux except:
    //  - all 6 args are passed in regs, rather than in a memory-block.
    //  - the file offset is specified in pagesize units rather than bytes,
    //    so that it can be used for files bigger than 2^32 bytes.
@@ -4555,7 +4397,7 @@
    if (ARG2 == 0) {
       /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
          shall be established. */
-      SET_RESULT( -VKI_EINVAL );
+      SET_STATUS_Failure( VKI_EINVAL );
       return;
    }
 
@@ -4563,13 +4405,13 @@
       /* zap any misaligned addresses. */
       /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
          to fail.   Here, we catch them all. */
-      SET_RESULT( -VKI_EINVAL );
+      SET_STATUS_Failure( VKI_EINVAL );
       return;
    }
 
    if (ARG4 & VKI_MAP_FIXED) {
       if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mmap2"))
-	 SET_RESULT( -VKI_ENOMEM );
+	 SET_STATUS_Failure( VKI_ENOMEM );
    } else {
       Addr a = VG_(find_map_space)(ARG1, ARG2, True);
       if (a == 0 && ARG1 != 0)
@@ -4577,7 +4419,7 @@
       else
          ARG1 = a;
       if (ARG1 == 0)
-	 SET_RESULT( -VKI_ENOMEM );
+	 SET_STATUS_Failure( VKI_ENOMEM );
       else 
          ARG4 |= VKI_MAP_FIXED;
    }
@@ -4585,19 +4427,20 @@
 
 POST(sys_mmap2)
 {
+   vg_assert(SUCCESS);
    vg_assert(VG_(valid_client_addr)(RES, ARG2, tid, "mmap2"));
-   mmap_segment( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
-                 ARG6 * (ULong)VKI_PAGE_SIZE );
+   VG_(mmap_segment)( (Addr)RES, ARG2, ARG3, ARG4, ARG5,
+                      ARG6 * (ULong)VKI_PAGE_SIZE );
 }
 
-PRE(sys_mprotect, 0)
+PRE(sys_mprotect)
 {
    PRINT("sys_mprotect ( %p, %llu, %d )", ARG1,(ULong)ARG2,ARG3);
    PRE_REG_READ3(long, "mprotect",
                  unsigned long, addr, vki_size_t, len, unsigned long, prot);
 
    if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "mprotect"))
-      SET_RESULT( -VKI_ENOMEM );
+      SET_STATUS_Failure( VKI_ENOMEM );
 }
 
 POST(sys_mprotect)
@@ -4614,13 +4457,14 @@
    VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
 }
 
-PRE(sys_munmap, 0)
+PRE(sys_munmap)
 {
+   if (0) VG_(printf)("  munmap( %p )\n", ARG1);
    PRINT("sys_munmap ( %p, %llu )", ARG1,(ULong)ARG2);
    PRE_REG_READ2(long, "munmap", unsigned long, start, vki_size_t, length);
 
    if (!VG_(valid_client_addr)(ARG1, ARG2, tid, "munmap"))
-      SET_RESULT( -VKI_EINVAL );
+      SET_STATUS_Failure( VKI_EINVAL );
 }
 
 POST(sys_munmap)
@@ -4633,22 +4477,23 @@
    VG_TRACK( die_mem_munmap, a, len );
 }
 
-PRE(sys_mincore, 0)
-{
-   PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
-   PRE_REG_READ3(long, "mincore",
-                 unsigned long, start, vki_size_t, length,
-                 unsigned char *, vec);
-   PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
-}
+//zz PRE(sys_mincore, 0)
+//zz {
+//zz    PRINT("sys_mincore ( %p, %llu, %p )", ARG1,(ULong)ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "mincore",
+//zz                  unsigned long, start, vki_size_t, length,
+//zz                  unsigned char *, vec);
+//zz    PRE_MEM_WRITE( "mincore(vec)", ARG3, (ARG2 + 4096 - 1) / 4096);
+//zz }
+//zz 
+//zz POST(sys_mincore)
+//zz {
+//zz    POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );  
+//zz }
 
-POST(sys_mincore)
+PRE(sys_nanosleep)
 {
-   POST_MEM_WRITE( ARG3, (ARG2 + 4096 - 1) / 4096 );  
-}
-
-PRE(sys_nanosleep, MayBlock|PostOnFail)
-{
+   *flags |= SfMayBlock|SfPostOnFail;
    PRINT("sys_nanosleep ( %p, %p )", ARG1,ARG2);
    PRE_REG_READ2(long, "nanosleep", 
                  struct timespec *, req, struct timespec *, rem);
@@ -4659,12 +4504,14 @@
 
 POST(sys_nanosleep)
 {
-   if (ARG2 != 0 && RES == -VKI_EINTR)
+   vg_assert(SUCCESS || FAILURE);
+   if (ARG2 != 0 && FAILURE && RES_unchecked == VKI_EINTR)
       POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
 }
 
-PRE(sys_open, MayBlock)
+PRE(sys_open)
 {
+   *flags |= SfMayBlock;
    if (ARG2 & VKI_O_CREAT) {
       // 3-arg version
       PRINT("sys_open ( %p(%s), %d, %d )",ARG1,ARG1,ARG2,ARG3);
@@ -4681,45 +4528,51 @@
 
 POST(sys_open)
 {
+   vg_assert(SUCCESS);
    if (!VG_(fd_allowed)(RES, "open", tid, True)) {
       VG_(close)(RES);
-      SET_RESULT( -VKI_EMFILE );
+      SET_STATUS_Failure( VKI_EMFILE );
    } else {
       if (VG_(clo_track_fds))
-         VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+         VG_(record_fd_open)(tid, RES, 
+                                  VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
    }
 }
 
-PRE(sys_read, MayBlock)
+PRE(sys_read)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_read ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
    PRE_REG_READ3(ssize_t, "read",
                  unsigned int, fd, char *, buf, vki_size_t, count);
 
    if (!VG_(fd_allowed)(ARG1, "read", tid, False))
-      SET_RESULT( -VKI_EBADF );
+      SET_STATUS_Failure( VKI_EBADF );
    else
       PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
 }
 
 POST(sys_read)
 {
+   vg_assert(SUCCESS);
    POST_MEM_WRITE( ARG2, RES );
 }
 
-PRE(sys_write, MayBlock)
+PRE(sys_write)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_write ( %d, %p, %llu )", ARG1, ARG2, (ULong)ARG3);
    PRE_REG_READ3(ssize_t, "write",
                  unsigned int, fd, const char *, buf, vki_size_t, count);
    if (!VG_(fd_allowed)(ARG1, "write", tid, False))
-      SET_RESULT( -VKI_EBADF );
+      SET_STATUS_Failure( VKI_EBADF );
    else
       PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
 }
 
-PRE(sys_creat, MayBlock)
+PRE(sys_creat)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_creat ( %p(%s), %d )", ARG1,ARG1,ARG2);
    PRE_REG_READ2(long, "creat", const char *, pathname, int, mode);
    PRE_MEM_RASCIIZ( "creat(pathname)", ARG1 );
@@ -4727,9 +4580,10 @@
 
 POST(sys_creat)
 {
+   vg_assert(SUCCESS);
    if (!VG_(fd_allowed)(RES, "creat", tid, True)) {
       VG_(close)(RES);
-      SET_RESULT( -VKI_EMFILE );
+      SET_STATUS_Failure( VKI_EMFILE );
    } else {
       if (VG_(clo_track_fds))
          VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
@@ -4737,7 +4591,7 @@
 }
 
 // XXX: sort of x86-specific
-PRE(sys_pipe, 0)
+PRE(sys_pipe)
 {
    PRINT("sys_pipe ( %p )", ARG1);
    PRE_REG_READ1(int, "pipe", unsigned long *, filedes);
@@ -4752,7 +4606,7 @@
        !VG_(fd_allowed)(p[1], "pipe", tid, True)) {
       VG_(close)(p[0]);
       VG_(close)(p[1]);
-      SET_RESULT( -VKI_EMFILE );
+      SET_STATUS_Failure( VKI_EMFILE );
    } else {
       POST_MEM_WRITE( ARG1, 2*sizeof(int) );
       if (VG_(clo_track_fds)) {
@@ -4763,7 +4617,7 @@
 }
 
 // XXX: x86-specific, due to pollfd struct
-PRE(sys_poll, MayBlock)
+PRE(sys_poll)
 {
    /* struct pollfd {
         int fd;           -- file descriptor
@@ -4773,6 +4627,7 @@
       int poll(struct pollfd *ufds, unsigned int nfds, int timeout) 
    */
    UInt i;
+   *flags |= SfMayBlock;
    struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
    PRINT("sys_poll ( %p, %d, %d )\n", ARG1,ARG2,ARG3);
    PRE_REG_READ3(long, "poll",
@@ -4799,9 +4654,9 @@
    }
 }
 
-PRE(sys_readlink, Special)
+PRE(sys_readlink)
 {
-   int saved = SYSNO;
+   Word saved = SYSNO;
    PRINT("sys_readlink ( %p, %p, %llu )", ARG1,ARG2,(ULong)ARG3);
    PRE_REG_READ3(long, "readlink",
                  const char *, path, char *, buf, int, bufsiz);
@@ -4813,33 +4668,36 @@
     * /proc/<pid>/exe.
     */
 
-   SET_RESULT( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
-   if ((Int)RES == -2) {
-      char name[25];
+   SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
 
+   /* jrs 20050604: where does the magic value 2 come from?  It seems
+      like it should be a kernel error value, but we don't know of any
+      such. */
+   if (SWHAT == SsFailure && RES_unchecked == 2) {
+      HChar name[25];
       VG_(sprintf)(name, "/proc/%d/exe", VG_(getpid)());
-   
       if (VG_(strcmp)((Char *)ARG1, name) == 0 ||
           VG_(strcmp)((Char *)ARG1, "/proc/self/exe") == 0) {
          VG_(sprintf)(name, "/proc/self/fd/%d", VG_(clexecfd));
-         SET_RESULT( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
+         SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, ARG2, ARG3));
       }
    }
 
-   if ((Int)RES > 0)
+   if (SUCCESS && RES > 0)
       POST_MEM_WRITE( ARG2, RES );
 }
 
-PRE(sys_readv, MayBlock)
+PRE(sys_readv)
 {
    Int i;
    struct vki_iovec * vec;
+   *flags |= SfMayBlock;
    PRINT("sys_readv ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
    PRE_REG_READ3(ssize_t, "readv",
                  unsigned long, fd, const struct iovec *, vector,
                  unsigned long, count);
    if (!VG_(fd_allowed)(ARG1, "readv", tid, False)) {
-      SET_RESULT( -VKI_EBADF );
+      SET_STATUS_Failure( VKI_EBADF );
    } else {
       PRE_MEM_READ( "readv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
 
@@ -4855,6 +4713,7 @@
 
 POST(sys_readv)
 {
+   vg_assert(SUCCESS);
    if (RES > 0) {
       Int i;
       struct vki_iovec * vec = (struct vki_iovec *)ARG2;
@@ -4871,7 +4730,7 @@
    }
 }
 
-PRE(sys_rename, 0)
+PRE(sys_rename)
 {
    PRINT("sys_rename ( %p, %p )", ARG1, ARG2 );
    PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath);
@@ -4879,41 +4738,42 @@
    PRE_MEM_RASCIIZ( "rename(newpath)", ARG2 );
 }
 
-PRE(sys_rmdir, MayBlock)
-{
-   PRINT("sys_rmdir ( %p )", ARG1);
-   PRE_REG_READ1(long, "rmdir", const char *, pathname);
-   PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
-}
+//zz PRE(sys_rmdir, SfMayBlock)
+//zz {
+//zz    PRINT("sys_rmdir ( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "rmdir", const char *, pathname);
+//zz    PRE_MEM_RASCIIZ( "rmdir(pathname)", ARG1 );
+//zz }
+//zz 
+//zz PRE(sys_sched_setparam, 0)
+//zz {
+//zz    PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
+//zz    PRE_REG_READ2(long, "sched_setparam", 
+//zz                  vki_pid_t, pid, struct sched_param *, p);
+//zz    PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
+//zz }
+//zz 
+//zz POST(sys_sched_setparam)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
+//zz }
+//zz 
+//zz PRE(sys_sched_getparam, 0)
+//zz {
+//zz    PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
+//zz    PRE_REG_READ2(long, "sched_getparam", 
+//zz                  vki_pid_t, pid, struct sched_param *, p);
+//zz    PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
+//zz }
+//zz 
+//zz POST(sys_sched_getparam)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
+//zz }
 
-PRE(sys_sched_setparam, 0)
+PRE(sys_select)
 {
-   PRINT("sched_setparam ( %d, %p )", ARG1, ARG2 );
-   PRE_REG_READ2(long, "sched_setparam", 
-                 vki_pid_t, pid, struct sched_param *, p);
-   PRE_MEM_READ( "sched_setparam(p)", ARG2, sizeof(struct vki_sched_param) );
-}
-
-POST(sys_sched_setparam)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
-}
-
-PRE(sys_sched_getparam, 0)
-{
-   PRINT("sched_getparam ( %d, %p )", ARG1, ARG2 );
-   PRE_REG_READ2(long, "sched_getparam", 
-                 vki_pid_t, pid, struct sched_param *, p);
-   PRE_MEM_WRITE( "sched_getparam(p)", ARG2, sizeof(struct vki_sched_param) );
-}
-
-POST(sys_sched_getparam)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_sched_param) );
-}
-
-PRE(sys_select, MayBlock)
-{
+   *flags |= SfMayBlock;
    PRINT("sys_select ( %d, %p, %p, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
    PRE_REG_READ5(long, "select",
                  int, n, vki_fd_set *, readfds, vki_fd_set *, writefds,
@@ -4932,65 +4792,65 @@
       PRE_MEM_READ( "select(timeout)", ARG5, sizeof(struct vki_timeval) );
 }
 
-PRE(sys_setgid16, 0)
-{
-   PRINT("sys_setgid16 ( %d )", ARG1);
-   PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
-}
+//zz PRE(sys_setgid16, 0)
+//zz {
+//zz    PRINT("sys_setgid16 ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setgid16", vki_old_gid_t, gid);
+//zz }
+//zz 
+//zz PRE(sys_setgid, 0)
+//zz {
+//zz    PRINT("sys_setgid ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
+//zz }
+//zz 
+//zz PRE(sys_setsid, 0)
+//zz {
+//zz    PRINT("sys_setsid ( )");
+//zz    PRE_REG_READ0(long, "setsid");
+//zz }
+//zz 
+//zz PRE(sys_setgroups16, 0)
+//zz {
+//zz    PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
+//zz    if (ARG1 > 0)
+//zz       PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
+//zz }
+//zz 
+//zz PRE(sys_setgroups, 0)
+//zz {
+//zz    PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
+//zz    if (ARG1 > 0)
+//zz       PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
+//zz }
+//zz 
+//zz PRE(sys_setpgid, 0)
+//zz {
+//zz    PRINT("setpgid ( %d, %d )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
+//zz }
+//zz 
+//zz PRE(sys_setregid, 0)
+//zz {
+//zz    PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
+//zz }
+//zz 
+//zz PRE(sys_setreuid16, 0)
+//zz {
+//zz    PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
+//zz }
+//zz 
+//zz PRE(sys_setreuid, 0)
+//zz {
+//zz    PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
+//zz    PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
+//zz }
 
-PRE(sys_setgid, 0)
-{
-   PRINT("sys_setgid ( %d )", ARG1);
-   PRE_REG_READ1(long, "setgid", vki_gid_t, gid);
-}
-
-PRE(sys_setsid, 0)
-{
-   PRINT("sys_setsid ( )");
-   PRE_REG_READ0(long, "setsid");
-}
-
-PRE(sys_setgroups16, 0)
-{
-   PRINT("sys_setgroups16 ( %llu, %p )", (ULong)ARG1, ARG2);
-   PRE_REG_READ2(long, "setgroups16", int, size, vki_old_gid_t *, list);
-   if (ARG1 > 0)
-      PRE_MEM_READ( "setgroups16(list)", ARG2, ARG1 * sizeof(vki_old_gid_t) );
-}
-
-PRE(sys_setgroups, 0)
-{
-   PRINT("setgroups ( %llu, %p )", (ULong)ARG1, ARG2);
-   PRE_REG_READ2(long, "setgroups", int, size, vki_gid_t *, list);
-   if (ARG1 > 0)
-      PRE_MEM_READ( "setgroups(list)", ARG2, ARG1 * sizeof(vki_gid_t) );
-}
-
-PRE(sys_setpgid, 0)
-{
-   PRINT("setpgid ( %d, %d )", ARG1, ARG2);
-   PRE_REG_READ2(long, "setpgid", vki_pid_t, pid, vki_pid_t, pgid);
-}
-
-PRE(sys_setregid, 0)
-{
-   PRINT("sys_setregid ( %d, %d )", ARG1, ARG2);
-   PRE_REG_READ2(long, "setregid", vki_gid_t, rgid, vki_gid_t, egid);
-}
-
-PRE(sys_setreuid16, 0)
-{
-   PRINT("setreuid16 ( 0x%x, 0x%x )", ARG1, ARG2);
-   PRE_REG_READ2(long, "setreuid16", vki_old_uid_t, ruid, vki_old_uid_t, euid);
-}
-
-PRE(sys_setreuid, 0)
-{
-   PRINT("sys_setreuid ( 0x%x, 0x%x )", ARG1, ARG2);
-   PRE_REG_READ2(long, "setreuid", vki_uid_t, ruid, vki_uid_t, euid);
-}
-
-PRE(sys_setrlimit, 0)
+PRE(sys_setrlimit)
 {
    PRINT("sys_setrlimit ( %d, %p )", ARG1,ARG2);
    PRE_REG_READ2(long, "setrlimit",
@@ -5000,372 +4860,97 @@
    if (ARG1 == VKI_RLIMIT_NOFILE) {
       if (((struct vki_rlimit *)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
           ((struct vki_rlimit *)ARG2)->rlim_max != VG_(fd_hard_limit)) {
-         SET_RESULT( -VKI_EPERM );
+         SET_STATUS_Failure( VKI_EPERM );
       }
       else {
          VG_(fd_soft_limit) = ((struct vki_rlimit *)ARG2)->rlim_cur;
-         SET_RESULT( 0 );
+         SET_STATUS_Success( 0 );
       }
    }
    else if (ARG1 == VKI_RLIMIT_DATA) {
       if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
           ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
-         SET_RESULT( -VKI_EPERM );
+         SET_STATUS_Failure( VKI_EPERM );
       }
       else {
          VG_(client_rlimit_data) = *(struct vki_rlimit *)ARG2;
-         SET_RESULT( 0 );
+         SET_STATUS_Success( 0 );
       }
    }
    else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) {
       if (((struct vki_rlimit *)ARG2)->rlim_cur > ((struct vki_rlimit *)ARG2)->rlim_max ||
           ((struct vki_rlimit *)ARG2)->rlim_max > ((struct vki_rlimit *)ARG2)->rlim_max) {
-         SET_RESULT( -VKI_EPERM );
+         SET_STATUS_Failure( VKI_EPERM );
       }
       else {
-         VG_(threads)[tid].client_stack_szB  = ((struct vki_rlimit *)ARG2)->rlim_cur;
+         VG_(threads)[tid].client_stack_szB = ((struct vki_rlimit *)ARG2)->rlim_cur;
          VG_(client_rlimit_stack) = *(struct vki_rlimit *)ARG2;
-         SET_RESULT( 0 );
+         SET_STATUS_Success( 0 );
       }
    }
 }
 
-PRE(sys_setuid16, 0)
+PRE(sys_setuid16)
 {
    PRINT("sys_setuid16 ( %d )", ARG1);
    PRE_REG_READ1(long, "setuid16", vki_old_uid_t, uid);
 }
 
-PRE(sys_setuid, 0)
-{
-   PRINT("sys_setuid ( %d )", ARG1);
-   PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
-}
+//zz PRE(sys_setuid, 0)
+//zz {
+//zz    PRINT("sys_setuid ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setuid", vki_uid_t, uid);
+//zz }
 
-PRE(sys_socketcall, MayBlock)
-{
-#  define ARG2_0  (((UWord*)ARG2)[0])
-#  define ARG2_1  (((UWord*)ARG2)[1])
-#  define ARG2_2  (((UWord*)ARG2)[2])
-#  define ARG2_3  (((UWord*)ARG2)[3])
-#  define ARG2_4  (((UWord*)ARG2)[4])
-#  define ARG2_5  (((UWord*)ARG2)[5])
+//zz PRE(sys_newstat, 0)
+//zz {
+//zz    PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
+//zz    PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
+//zz    PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz 
+//zz POST(sys_newstat)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
+//zz }
+//zz 
+//zz PRE(sys_statfs, 0)
+//zz {
+//zz    PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
+//zz    PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
+//zz    PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz 
+//zz POST(sys_statfs)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
+//zz }
+//zz 
+//zz PRE(sys_statfs64, 0)
+//zz {
+//zz    PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "statfs64",
+//zz                  const char *, path, vki_size_t, size, struct statfs64 *, buf);
+//zz    PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
+//zz    PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
+//zz }
+//zz 
+//zz POST(sys_statfs64)
+//zz {
+//zz    POST_MEM_WRITE( ARG3, ARG2 );
+//zz }
+//zz 
+//zz PRE(sys_symlink, SfMayBlock)
+//zz {
+//zz    PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
+//zz    PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
+//zz    PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
+//zz }
 
-   PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
-   PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
-
-   switch (ARG1 /* request */) {
-
-   case VKI_SYS_SOCKETPAIR:
-      /* int socketpair(int d, int type, int protocol, int sv[2]); */
-      PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
-      VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
-      break;
-
-   case VKI_SYS_SOCKET:
-      /* int socket(int domain, int type, int protocol); */
-      PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
-      break;
-
-   case VKI_SYS_BIND:
-      /* int bind(int sockfd, struct sockaddr *my_addr, 
-	 int addrlen); */
-      PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
-      VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-               
-   case VKI_SYS_LISTEN:
-      /* int listen(int s, int backlog); */
-      PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
-      break;
-
-   case VKI_SYS_ACCEPT: {
-      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
-      PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
-      VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-   }
-
-   case VKI_SYS_SENDTO:
-      /* int sendto(int s, const void *msg, int len, 
-                    unsigned int flags, 
-                    const struct sockaddr *to, int tolen); */
-      PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
-      VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2, 
-                                   ARG2_3, ARG2_4, ARG2_5 );
-      break;
-
-   case VKI_SYS_SEND:
-      /* int send(int s, const void *msg, size_t len, int flags); */
-      PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
-      VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_RECVFROM:
-      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
-	 struct sockaddr *from, int *fromlen); */
-      PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
-      VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2, 
-                                     ARG2_3, ARG2_4, ARG2_5 );
-      break;
-   
-   case VKI_SYS_RECV:
-      /* int recv(int s, void *buf, int len, unsigned int flags); */
-      /* man 2 recv says:
-	 The  recv call is normally used only on a connected socket
-	 (see connect(2)) and is identical to recvfrom with a  NULL
-	 from parameter.
-      */
-      PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
-      VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_CONNECT:
-      /* int connect(int sockfd, 
-                     struct sockaddr *serv_addr, int addrlen ); */
-      PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
-      VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_SETSOCKOPT:
-      /* int setsockopt(int s, int level, int optname, 
-                        const void *optval, int optlen); */
-      PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
-      VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 
-                                       ARG2_3, ARG2_4 );
-      break;
-
-   case VKI_SYS_GETSOCKOPT:
-      /* int getsockopt(int s, int level, int optname, 
-                        void *optval, socklen_t *optlen); */
-      PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
-      VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 
-                                       ARG2_3, ARG2_4 );
-      break;
-
-   case VKI_SYS_GETSOCKNAME:
-      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
-      PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
-      VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_GETPEERNAME:
-      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
-      PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
-      VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_SHUTDOWN:
-      /* int shutdown(int s, int how); */
-      PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
-      break;
-
-   case VKI_SYS_SENDMSG: {
-      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
-
-      /* this causes warnings, and I don't get why. glibc bug?
-       * (after all it's glibc providing the arguments array)
-       PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
-      */
-      VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
-      break;
-   }
-      
-   case VKI_SYS_RECVMSG: {
-      /* int recvmsg(int s, struct msghdr *msg, int flags); */
-
-      /* this causes warnings, and I don't get why. glibc bug?
-       * (after all it's glibc providing the arguments array)
-       PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
-      */
-      VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
-      break;
-   }
-
-   default:
-      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
-      SET_RESULT( -VKI_EINVAL );
-      break;
-   }
-#  undef ARG2_0
-#  undef ARG2_1
-#  undef ARG2_2
-#  undef ARG2_3
-#  undef ARG2_4
-#  undef ARG2_5
-}
-
-POST(sys_socketcall)
-{
-#  define ARG2_0  (((UWord*)ARG2)[0])
-#  define ARG2_1  (((UWord*)ARG2)[1])
-#  define ARG2_2  (((UWord*)ARG2)[2])
-#  define ARG2_3  (((UWord*)ARG2)[3])
-#  define ARG2_4  (((UWord*)ARG2)[4])
-#  define ARG2_5  (((UWord*)ARG2)[5])
-
-   UWord r;
-   switch (ARG1 /* request */) {
-
-   case VKI_SYS_SOCKETPAIR:
-      VG_(generic_POST_sys_socketpair)( tid, RES, ARG2_0, 
-                                        ARG2_1, ARG2_2, ARG2_3 );
-      break;
-
-   case VKI_SYS_SOCKET:
-     r = VG_(generic_POST_sys_socket)( tid, RES );
-     SET_RESULT(r);
-     break;
-
-   case VKI_SYS_BIND:
-      /* int bind(int sockfd, struct sockaddr *my_addr, 
-			int addrlen); */
-      break;
-               
-   case VKI_SYS_LISTEN:
-      /* int listen(int s, int backlog); */
-      break;
-
-   case VKI_SYS_ACCEPT:
-      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
-     r = VG_(generic_POST_sys_accept)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
-     SET_RESULT(r);
-     break;
-
-   case VKI_SYS_SENDTO:
-      break;
-
-   case VKI_SYS_SEND:
-      break;
-
-   case VKI_SYS_RECVFROM:
-      VG_(generic_POST_sys_recvfrom)( tid, RES, ARG2_0, ARG2_1, ARG2_2,
-                                           ARG2_3, ARG2_4, ARG2_5 );
-      break;
-
-   case VKI_SYS_RECV:
-      VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_CONNECT:
-      break;
-
-   case VKI_SYS_SETSOCKOPT:
-      break;
-
-   case VKI_SYS_GETSOCKOPT:
-      VG_(generic_POST_sys_getsockopt)( tid, RES, ARG2_0, ARG2_1, 
-                                             ARG2_2, ARG2_3, ARG2_4 );
-      break;
-
-   case VKI_SYS_GETSOCKNAME:
-      VG_(generic_POST_sys_getsockname)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_GETPEERNAME:
-      VG_(generic_POST_sys_getpeername)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
-      break;
-
-   case VKI_SYS_SHUTDOWN:
-      break;
-
-   case VKI_SYS_SENDMSG:
-      break;
-
-   case VKI_SYS_RECVMSG:
-     VG_(generic_POST_sys_recvmsg)( tid, RES, ARG2_0, ARG2_1 );
-     break;
-
-   default:
-      VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
-      VG_(core_panic)("... bye!\n");
-      break; /*NOTREACHED*/
-   }
-#  undef ARG2_0
-#  undef ARG2_1
-#  undef ARG2_2
-#  undef ARG2_3
-#  undef ARG2_4
-#  undef ARG2_5
-}
-
-PRE(sys_newstat, 0)
-{
-   PRINT("sys_newstat ( %p(%s), %p )", ARG1,ARG1,ARG2);
-   PRE_REG_READ2(long, "stat", char *, file_name, struct stat *, buf);
-   PRE_MEM_RASCIIZ( "stat(file_name)", ARG1 );
-   PRE_MEM_WRITE( "stat(buf)", ARG2, sizeof(struct vki_stat) );
-}
-
-POST(sys_newstat)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat) );
-}
-
-PRE(sys_statfs, 0)
-{
-   PRINT("sys_statfs ( %p, %p )",ARG1,ARG2);
-   PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
-   PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
-   PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct vki_statfs) );
-}
-
-POST(sys_statfs)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_statfs) );
-}
-
-PRE(sys_statfs64, 0)
-{
-   PRINT("sys_statfs64 ( %p, %llu, %p )",ARG1,(ULong)ARG2,ARG3);
-   PRE_REG_READ3(long, "statfs64",
-                 const char *, path, vki_size_t, size, struct statfs64 *, buf);
-   PRE_MEM_RASCIIZ( "statfs64(path)", ARG1 );
-   PRE_MEM_WRITE( "statfs64(buf)", ARG3, ARG2 );
-}
-
-POST(sys_statfs64)
-{
-   POST_MEM_WRITE( ARG3, ARG2 );
-}
-
-PRE(sys_symlink, MayBlock)
-{
-   PRINT("sys_symlink ( %p, %p )",ARG1,ARG2);
-   PRE_REG_READ2(long, "symlink", const char *, oldpath, const char *, newpath);
-   PRE_MEM_RASCIIZ( "symlink(oldpath)", ARG1 );
-   PRE_MEM_RASCIIZ( "symlink(newpath)", ARG2 );
-}
-
-// See comment above PRE(sys_lstat64) for an explanation of this #ifdef.
-#ifndef __amd64__
-PRE(sys_stat64, 0)
-{
-   PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
-   PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
-   PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
-   PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
-}
-
-POST(sys_stat64)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
-}
-
-PRE(sys_fstat64, 0)
-{
-   PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
-   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
-   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
-}
-
-POST(sys_fstat64)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
-}
-#endif
-
-PRE(sys_time, 0)
+PRE(sys_time)
 {
    /* time_t time(time_t *t); */
    PRINT("sys_time ( %p )",ARG1);
@@ -5382,34 +4967,35 @@
    }
 }
 
-PRE(sys_times, 0)
-{
-   PRINT("sys_times ( %p )", ARG1);
-   PRE_REG_READ1(long, "times", struct tms *, buf);
-   PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
-}
+//zz PRE(sys_times, 0)
+//zz {
+//zz    PRINT("sys_times ( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "times", struct tms *, buf);
+//zz    PRE_MEM_WRITE( "times(buf)", ARG1, sizeof(struct vki_tms) );
+//zz }
+//zz 
+//zz POST(sys_times)
+//zz {
+//zz    if (ARG1 != 0) {
+//zz       POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_umask, 0)
+//zz {
+//zz    PRINT("sys_umask ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "umask", int, mask);
+//zz }
 
-POST(sys_times)
+PRE(sys_unlink)
 {
-   if (ARG1 != 0) {
-      POST_MEM_WRITE( ARG1, sizeof(struct vki_tms) );
-   }
-}
-
-PRE(sys_umask, 0)
-{
-   PRINT("sys_umask ( %d )", ARG1);
-   PRE_REG_READ1(long, "umask", int, mask);
-}
-
-PRE(sys_unlink, MayBlock)
-{
+   *flags |= SfMayBlock;
    PRINT("sys_unlink ( %p(%s) )", ARG1,ARG1);
    PRE_REG_READ1(long, "unlink", const char *, pathname);
    PRE_MEM_RASCIIZ( "unlink(pathname)", ARG1 );
 }
 
-PRE(sys_newuname, 0)
+PRE(sys_newuname)
 {
    PRINT("sys_newuname ( %p )", ARG1);
    PRE_REG_READ1(long, "uname", struct new_utsname *, buf);
@@ -5423,17 +5009,18 @@
    }
 }
 
-PRE(sys_utime, MayBlock)
-{
-   PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
-   PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
-   if (ARG2 != 0)
-      PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
-}
+//zz PRE(sys_utime, SfMayBlock)
+//zz {
+//zz    PRINT("sys_utime ( %p, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "utime", char *, filename, struct utimbuf *, buf);
+//zz    PRE_MEM_RASCIIZ( "utime(filename)", ARG1 );
+//zz    if (ARG2 != 0)
+//zz       PRE_MEM_READ( "utime(buf)", ARG2, sizeof(struct vki_utimbuf) );
+//zz }
 
-PRE(sys_waitpid, MayBlock)
+PRE(sys_waitpid)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_waitpid ( %d, %p, %d )", ARG1,ARG2,ARG3);
    PRE_REG_READ3(long, "waitpid", 
                  vki_pid_t, pid, unsigned int *, status, int, options);
@@ -5448,8 +5035,9 @@
       POST_MEM_WRITE( ARG2, sizeof(int) );
 }
 
-PRE(sys_wait4, MayBlock)
+PRE(sys_wait4)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_wait4 ( %d, %p, %d, %p )", ARG1,ARG2,ARG3,ARG4);
 
    PRE_REG_READ4(long, "wait4", 
@@ -5469,16 +5057,17 @@
       POST_MEM_WRITE( ARG4, sizeof(struct vki_rusage) );
 }
 
-PRE(sys_writev, MayBlock)
+PRE(sys_writev)
 {
    Int i;
    struct vki_iovec * vec;
+   *flags |= SfMayBlock;
    PRINT("sys_writev ( %d, %p, %llu )",ARG1,ARG2,(ULong)ARG3);
    PRE_REG_READ3(ssize_t, "writev",
                  unsigned long, fd, const struct iovec *, vector,
                  unsigned long, count);
    if (!VG_(fd_allowed)(ARG1, "writev", tid, False)) {
-      SET_RESULT( -VKI_EBADF );
+      SET_STATUS_Failure( VKI_EBADF );
    } else {
       PRE_MEM_READ( "writev(vector)", 
 		     ARG2, ARG3 * sizeof(struct vki_iovec) );
@@ -5492,69 +5081,70 @@
    }
 }
 
-PRE(sys_utimes, 0)
-{
-   PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
-   PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
-   if (ARG2 != 0)
-      PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
-}
+//zz PRE(sys_utimes, 0)
+//zz {
+//zz    PRINT("sys_utimes ( %p, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp);
+//zz    PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 );
+//zz    if (ARG2 != 0)
+//zz       PRE_MEM_READ( "utimes(tvp)", ARG2, sizeof(struct vki_timeval) );
+//zz }
+//zz 
+//zz PRE(sys_sched_setaffinity, 0)
+//zz {
+//zz    PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "sched_setaffinity", 
+//zz                  vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
+//zz    PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
+//zz }
+//zz 
+//zz PRE(sys_sched_getaffinity, 0)
+//zz {
+//zz    PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "sched_getaffinity", 
+//zz                  vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
+//zz    PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
+//zz }
+//zz 
+//zz POST(sys_sched_getaffinity)
+//zz {
+//zz    POST_MEM_WRITE(ARG3, ARG2);
+//zz }
+//zz 
+//zz PRE(sys_acct, 0)
+//zz {
+//zz    PRINT("sys_acct ( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "acct", const char *, filename);
+//zz    PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
+//zz }
 
-PRE(sys_sched_setaffinity, 0)
+PRE(sys_pause)
 {
-   PRINT("sched_setaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "sched_setaffinity", 
-                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
-   PRE_MEM_READ( "sched_setaffinity(mask)", ARG3, ARG2);
-}
-
-PRE(sys_sched_getaffinity, 0)
-{
-   PRINT("sched_getaffinity ( %d, %d, %p )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "sched_getaffinity", 
-                 vki_pid_t, pid, unsigned int, len, unsigned long *, mask);
-   PRE_MEM_WRITE( "sched_getaffinity(mask)", ARG3, ARG2);
-}
-
-POST(sys_sched_getaffinity)
-{
-   POST_MEM_WRITE(ARG3, ARG2);
-}
-
-PRE(sys_acct, 0)
-{
-   PRINT("sys_acct ( %p )", ARG1);
-   PRE_REG_READ1(long, "acct", const char *, filename);
-   PRE_MEM_RASCIIZ( "acct(filename)", ARG1 );
-}
-
-PRE(sys_pause, MayBlock)
-{
+   *flags |= SfMayBlock;
    PRINT("sys_pause ( )");
    PRE_REG_READ0(long, "pause");
 }
 
-// XXX: x86-specific
-PRE(sys_sigsuspend, MayBlock)
-{
-   /* The C library interface to sigsuspend just takes a pointer to
-      a signal mask but this system call has three arguments - the first
-      two don't appear to be used by the kernel and are always passed as
-      zero by glibc and the third is the first word of the signal mask
-      so only 32 signals are supported.
-     
-      In fact glibc normally uses rt_sigsuspend if it is available as
-      that takes a pointer to the signal mask so supports more signals.
-    */
-   PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
-   PRE_REG_READ3(int, "sigsuspend",
-                 int, history0, int, history1,
-                 vki_old_sigset_t, mask);
-}
+//zz // XXX: x86-specific
+//zz PRE(sys_sigsuspend, SfMayBlock)
+//zz {
+//zz    /* The C library interface to sigsuspend just takes a pointer to
+//zz       a signal mask but this system call has three arguments - the first
+//zz       two don't appear to be used by the kernel and are always passed as
+//zz       zero by glibc and the third is the first word of the signal mask
+//zz       so only 32 signals are supported.
+//zz      
+//zz       In fact glibc normally uses rt_sigsuspend if it is available as
+//zz       that takes a pointer to the signal mask so supports more signals.
+//zz     */
+//zz    PRINT("sys_sigsuspend ( %d, %d, %d )", ARG1,ARG2,ARG3 );
+//zz    PRE_REG_READ3(int, "sigsuspend",
+//zz                  int, history0, int, history1,
+//zz                  vki_old_sigset_t, mask);
+//zz }
 
 // XXX: x86-specific
-PRE(sys_rt_sigsuspend, MayBlock)
+PRE(sys_rt_sigsuspend)
 {
    /* The C library interface to sigsuspend just takes a pointer to
       a signal mask but this system call has two arguments - a pointer
@@ -5562,6 +5152,7 @@
       on the size being equal to sizeof(sigset_t) however and will just
       return EINVAL if it isn't.
     */
+   *flags |= SfMayBlock;
    PRINT("sys_rt_sigsuspend ( %p, %d )", ARG1,ARG2 );
    PRE_REG_READ2(int, "rt_sigsuspend", vki_sigset_t *, mask, vki_size_t, size)
    if (ARG1 != (Addr)NULL) {
@@ -5569,8 +5160,9 @@
    }
 }
 
-PRE(sys_rt_sigtimedwait, MayBlock)
+PRE(sys_rt_sigtimedwait)
 {
+   *flags |= SfMayBlock;
    PRINT("sys_rt_sigtimedwait ( %p, %p, %p, %lld )",
          ARG1,ARG2,ARG3,(ULong)ARG4);
    PRE_REG_READ4(long, "rt_sigtimedwait", 
@@ -5590,28 +5182,28 @@
       POST_MEM_WRITE( ARG2, sizeof(vki_siginfo_t) );
 }
 
-PRE(sys_rt_sigqueueinfo, 0)
-{
-   PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "rt_sigqueueinfo", 
-                 int, pid, int, sig, vki_siginfo_t *, uinfo);
-   if (ARG2 != 0)
-      PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
-}
-
-POST(sys_rt_sigqueueinfo)
-{
-   PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "rt_sigqueueinfo",
-                 int, pid, int, sig, vki_siginfo_t *, uinfo);
-   if (ARG2 != 0)
-      PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
-   if (!VG_(client_signal_OK)(ARG2))
-      SET_RESULT( -VKI_EINVAL );
-}
+//zz PRE(sys_rt_sigqueueinfo, 0)
+//zz {
+//zz    PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "rt_sigqueueinfo", 
+//zz                  int, pid, int, sig, vki_siginfo_t *, uinfo);
+//zz    if (ARG2 != 0)
+//zz       PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
+//zz }
+//zz 
+//zz POST(sys_rt_sigqueueinfo)
+//zz {
+//zz    PRINT("sys_rt_sigqueueinfo(%d, %d, %p)", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "rt_sigqueueinfo",
+//zz                  int, pid, int, sig, vki_siginfo_t *, uinfo);
+//zz    if (ARG2 != 0)
+//zz       PRE_MEM_READ( "rt_sigqueueinfo(uinfo)", ARG3, sizeof(vki_siginfo_t) );
+//zz    if (!VG_(client_signal_OK)(ARG2))
+//zz       SET_STATUS_( -VKI_EINVAL );
+//zz }
 
 // XXX: x86-specific
-PRE(sys_sigaltstack, Special)
+PRE(sys_sigaltstack)
 {
    /* int sigaltstack(const stack_t *ss, stack_t *oss); */
    PRINT("sigaltstack ( %p, %p )",ARG1,ARG2);
@@ -5624,18 +5216,21 @@
       PRE_MEM_WRITE( "sigaltstack(oss)", ARG2, sizeof(vki_stack_t) );
    }
 
-   SET_RESULT( VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1, 
-                                             (vki_stack_t*)ARG2) );
+   SET_STATUS_from_SysRes( 
+      VG_(do_sys_sigaltstack) (tid, (vki_stack_t*)ARG1, 
+                              (vki_stack_t*)ARG2)
+   );
 }
 
 POST(sys_sigaltstack)
 {
+   vg_assert(SUCCESS);
    if (RES == 0 && ARG2 != 0)
       POST_MEM_WRITE( ARG2, sizeof(vki_stack_t));
 }
 
 // XXX: x86-specific
-PRE(sys_rt_sigaction, Special)
+PRE(sys_rt_sigaction)
 {
    PRINT("sys_rt_sigaction ( %d, %p, %p, %d )", ARG1,ARG2,ARG3,ARG4);
    PRE_REG_READ4(long, "rt_sigaction",
@@ -5651,7 +5246,7 @@
    // sys_rt_sigaction... perhaps this function should be renamed
    // VG_(do_sys_rt_sigaction)()  --njn
 
-   SET_RESULT(
+   SET_STATUS_from_SysRes(
       VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
                             (struct vki_sigaction *)ARG3)
    );
@@ -5659,6 +5254,7 @@
 
 POST(sys_rt_sigaction)
 {
+   vg_assert(SUCCESS);
    if (RES == 0 && ARG3 != 0)
       POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
 }
@@ -5666,8 +5262,8 @@
 // XXX: This syscall is not used on amd64 -- it only provides
 //      sys_rt_sigprocmask, which uses sigset_t rather than old_sigset_t.
 // This wrapper is only suitable for 32-bit architectures.
-#ifndef __amd64__
-PRE(sys_sigprocmask, Special)
+#if defined(VGP_x86_linux)
+PRE(sys_sigprocmask)
 {
    vki_old_sigset_t* set;
    vki_old_sigset_t* oldset;
@@ -5692,7 +5288,7 @@
    if (set)
       bigger_set.sig[0] = *(vki_old_sigset_t*)set;
 
-   SET_RESULT(
+   SET_STATUS_from_SysRes(
       VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, 
                                 set ? &bigger_set    : NULL,
                              oldset ? &bigger_oldset : NULL)
@@ -5700,16 +5296,20 @@
 
    if (oldset)
       *oldset = bigger_oldset.sig[0];
+
+   if (SUCCESS)
+      *flags |= SfPollAfter;
 }
 
 POST(sys_sigprocmask)
 {
+   vg_assert(SUCCESS);
    if (RES == 0 && ARG3 != 0)
       POST_MEM_WRITE( ARG3, sizeof(vki_old_sigset_t));
 }
 #endif
 
-PRE(sys_rt_sigprocmask, Special)
+PRE(sys_rt_sigprocmask)
 {
    PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
    PRE_REG_READ4(long, "rt_sigprocmask", 
@@ -5722,235 +5322,240 @@
 
    // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
    if (sizeof(vki_sigset_t) != ARG4)
-      SET_RESULT( -VKI_EMFILE );
+      SET_STATUS_Failure( VKI_EMFILE );
    else {
-      SET_RESULT( VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, 
+      SET_STATUS_from_SysRes( 
+                  VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/, 
                                             (vki_sigset_t*) ARG2,
                                             (vki_sigset_t*) ARG3 )
       );
    }
+
+   if (SUCCESS)
+      *flags |= SfPollAfter;
 }
 
 POST(sys_rt_sigprocmask)
 {
+   vg_assert(SUCCESS);
    if (RES == 0 && ARG3 != 0)
       POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
 }
 
-PRE(sys_sigpending, 0)
-{
-   PRINT( "sys_sigpending ( %p )", ARG1 );
-   PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
-   PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
-}
+//zz PRE(sys_sigpending, 0)
+//zz {
+//zz    PRINT( "sys_sigpending ( %p )", ARG1 );
+//zz    PRE_REG_READ1(long, "sigpending", vki_old_sigset_t *, set);
+//zz    PRE_MEM_WRITE( "sigpending(set)", ARG1, sizeof(vki_old_sigset_t));
+//zz }
+//zz 
+//zz POST(sys_sigpending)
+//zz {
+//zz    POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
+//zz }
+//zz 
+//zz PRE(sys_rt_sigpending, 0)
+//zz {
+//zz    PRINT( "sys_rt_sigpending ( %p )", ARG1 );
+//zz    PRE_REG_READ2(long, "rt_sigpending", 
+//zz                  vki_sigset_t *, set, vki_size_t, sigsetsize);
+//zz    PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
+//zz }
+//zz 
+//zz POST(sys_rt_sigpending)
+//zz {
+//zz    POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
+//zz }
+//zz 
+//zz PRE(sys_mq_open, 0)
+//zz {
+//zz    PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
+//zz          ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
+//zz    PRE_REG_READ4(long, "mq_open",
+//zz                  const char *, name, int, oflag, vki_mode_t, mode,
+//zz                  struct mq_attr *, attr);
+//zz    PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
+//zz    if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
+//zz       const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
+//zz       PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
+//zz                      (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
+//zz       PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
+//zz                      (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
+//zz    }
+//zz }
+//zz 
+//zz POST(sys_mq_open)
+//zz {
+//zz    if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
+//zz       VG_(close)(RES);
+//zz       SET_STATUS_( -VKI_EMFILE );
+//zz    } else {
+//zz       if (VG_(clo_track_fds))
+//zz          VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_mq_unlink, 0)
+//zz {
+//zz    PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
+//zz    PRE_REG_READ1(long, "mq_unlink", const char *, name);
+//zz    PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
+//zz }
+//zz 
+//zz PRE(sys_mq_timedsend, SfMayBlock)
+//zz {
+//zz    PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
+//zz          ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
+//zz    PRE_REG_READ5(long, "mq_timedsend",
+//zz                  vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
+//zz                  unsigned int, msg_prio, const struct timespec *, abs_timeout);
+//zz    if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
+//zz       SET_STATUS_( -VKI_EBADF );
+//zz    } else {
+//zz       PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
+//zz       if (ARG5 != 0)
+//zz          PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
+//zz                         sizeof(struct vki_timespec) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_mq_timedreceive, SfMayBlock)
+//zz {
+//zz    PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
+//zz          ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
+//zz    PRE_REG_READ5(ssize_t, "mq_timedreceive",
+//zz                  vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
+//zz                  unsigned int *, msg_prio,
+//zz                  const struct timespec *, abs_timeout);
+//zz    if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
+//zz       SET_STATUS_( -VKI_EBADF );
+//zz    } else {
+//zz       PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
+//zz       if (ARG4 != 0)
+//zz          PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
+//zz                         ARG4, sizeof(unsigned int) );
+//zz       if (ARG5 != 0)
+//zz          PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
+//zz                         ARG5, sizeof(struct vki_timespec) );
+//zz    }
+//zz }
+//zz 
+//zz POST(sys_mq_timedreceive)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, ARG3 );
+//zz    if (ARG4 != 0)
+//zz       POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
+//zz }
+//zz 
+//zz PRE(sys_mq_notify, 0)
+//zz {
+//zz    PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
+//zz    PRE_REG_READ2(long, "mq_notify",
+//zz                  vki_mqd_t, mqdes, const struct sigevent *, notification);
+//zz    if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
+//zz       SET_STATUS_( -VKI_EBADF );
+//zz    else if (ARG2 != 0)
+//zz       PRE_MEM_READ( "mq_notify(notification)",
+//zz                     ARG2, sizeof(struct vki_sigevent) );
+//zz }
+//zz 
+//zz PRE(sys_mq_getsetattr, 0)
+//zz {
+//zz    PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
+//zz    PRE_REG_READ3(long, "mq_getsetattr",
+//zz                  vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
+//zz                  struct mq_attr *, omqstat);
+//zz    if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
+//zz       SET_STATUS_( -VKI_EBADF );
+//zz    } else {
+//zz       if (ARG2 != 0) {
+//zz          const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
+//zz          PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
+//zz                         (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
+//zz       }
+//zz       if (ARG3 != 0)
+//zz          PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
+//zz                         sizeof(struct vki_mq_attr) );
+//zz    }   
+//zz }
+//zz 
+//zz POST(sys_mq_getsetattr)
+//zz {
+//zz    if (ARG3 != 0)
+//zz       POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
+//zz }
+//zz 
+//zz PRE(sys_timer_create, 0)
+//zz {
+//zz    PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "timer_create",
+//zz                  vki_clockid_t, clockid, struct sigevent *, evp,
+//zz                  vki_timer_t *, timerid);
+//zz    if (ARG2 != 0)
+//zz       PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
+//zz    PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
+//zz }
+//zz 
+//zz POST(sys_timer_create)
+//zz {
+//zz    POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
+//zz }
+//zz 
+//zz PRE(sys_timer_settime, 0)
+//zz {
+//zz    PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
+//zz    PRE_REG_READ4(long, "timer_settime", 
+//zz                  vki_timer_t, timerid, int, flags,
+//zz                  const struct itimerspec *, value,
+//zz                  struct itimerspec *, ovalue);
+//zz    PRE_MEM_READ( "timer_settime(value)", ARG3,
+//zz                   sizeof(struct vki_itimerspec) );
+//zz    if (ARG4 != 0)
+//zz        PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
+//zz                       sizeof(struct vki_itimerspec) );
+//zz }
+//zz 
+//zz POST(sys_timer_settime)
+//zz {
+//zz    if (ARG4 != 0)
+//zz       POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
+//zz }
+//zz 
+//zz PRE(sys_timer_gettime, 0)
+//zz {
+//zz    PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "timer_gettime", 
+//zz                  vki_timer_t, timerid, struct itimerspec *, value);
+//zz    PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
+//zz                   sizeof(struct vki_itimerspec));
+//zz }
+//zz 
+//zz POST(sys_timer_gettime)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
+//zz }
+//zz 
+//zz PRE(sys_timer_getoverrun, 0)
+//zz {
+//zz    PRINT("sys_timer_getoverrun( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
+//zz }
+//zz 
+//zz PRE(sys_timer_delete, 0)
+//zz {
+//zz    PRINT("sys_timer_delete( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
+//zz }
+//zz 
+//zz PRE(sys_clock_settime, 0)
+//zz {
+//zz    PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "clock_settime", 
+//zz                  vki_clockid_t, clk_id, const struct timespec *, tp);
+//zz    PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
+//zz }
 
-POST(sys_sigpending)
-{
-   POST_MEM_WRITE( ARG1, sizeof(vki_old_sigset_t) ) ;
-}
-
-PRE(sys_rt_sigpending, 0)
-{
-   PRINT( "sys_rt_sigpending ( %p )", ARG1 );
-   PRE_REG_READ2(long, "rt_sigpending", 
-                 vki_sigset_t *, set, vki_size_t, sigsetsize);
-   PRE_MEM_WRITE( "rt_sigpending(set)", ARG1, sizeof(vki_sigset_t));
-}
-
-POST(sys_rt_sigpending)
-{
-   POST_MEM_WRITE( ARG1, sizeof(vki_sigset_t) ) ;
-}
-
-PRE(sys_mq_open, 0)
-{
-   PRINT("sys_mq_open( %p(%s), %d, %lld, %p )",
-         ARG1,ARG1,ARG2,(ULong)ARG3,ARG4);
-   PRE_REG_READ4(long, "mq_open",
-                 const char *, name, int, oflag, vki_mode_t, mode,
-                 struct mq_attr *, attr);
-   PRE_MEM_RASCIIZ( "mq_open(name)", ARG1 );
-   if ((ARG2 & VKI_O_CREAT) != 0 && ARG4 != 0) {
-      const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG4;
-      PRE_MEM_READ( "mq_open(attr->mq_maxmsg)",
-                     (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
-      PRE_MEM_READ( "mq_open(attr->mq_msgsize)",
-                     (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
-   }
-}
-
-POST(sys_mq_open)
-{
-   if (!VG_(fd_allowed)(RES, "mq_open", tid, True)) {
-      VG_(close)(RES);
-      SET_RESULT( -VKI_EMFILE );
-   } else {
-      if (VG_(clo_track_fds))
-         VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
-   }
-}
-
-PRE(sys_mq_unlink, 0)
-{
-   PRINT("sys_mq_unlink ( %p(%s) )", ARG1,ARG1);
-   PRE_REG_READ1(long, "mq_unlink", const char *, name);
-   PRE_MEM_RASCIIZ( "mq_unlink(name)", ARG1 );
-}
-
-PRE(sys_mq_timedsend, MayBlock)
-{
-   PRINT("sys_mq_timedsend ( %d, %p, %llu, %d, %p )",
-         ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
-   PRE_REG_READ5(long, "mq_timedsend",
-                 vki_mqd_t, mqdes, const char *, msg_ptr, vki_size_t, msg_len,
-                 unsigned int, msg_prio, const struct timespec *, abs_timeout);
-   if (!VG_(fd_allowed)(ARG1, "mq_timedsend", tid, False)) {
-      SET_RESULT( -VKI_EBADF );
-   } else {
-      PRE_MEM_READ( "mq_timedsend(msg_ptr)", ARG2, ARG3 );
-      if (ARG5 != 0)
-         PRE_MEM_READ( "mq_timedsend(abs_timeout)", ARG5,
-                        sizeof(struct vki_timespec) );
-   }
-}
-
-PRE(sys_mq_timedreceive, MayBlock)
-{
-   PRINT("sys_mq_timedreceive( %d, %p, %llu, %p, %p )",
-         ARG1,ARG2,(ULong)ARG3,ARG4,ARG5);
-   PRE_REG_READ5(ssize_t, "mq_timedreceive",
-                 vki_mqd_t, mqdes, char *, msg_ptr, vki_size_t, msg_len,
-                 unsigned int *, msg_prio,
-                 const struct timespec *, abs_timeout);
-   if (!VG_(fd_allowed)(ARG1, "mq_timedreceive", tid, False)) {
-      SET_RESULT( -VKI_EBADF );
-   } else {
-      PRE_MEM_WRITE( "mq_timedreceive(msg_ptr)", ARG2, ARG3 );
-      if (ARG4 != 0)
-         PRE_MEM_WRITE( "mq_timedreceive(msg_prio)",
-                        ARG4, sizeof(unsigned int) );
-      if (ARG5 != 0)
-         PRE_MEM_READ( "mq_timedreceive(abs_timeout)",
-                        ARG5, sizeof(struct vki_timespec) );
-   }
-}
-
-POST(sys_mq_timedreceive)
-{
-   POST_MEM_WRITE( ARG2, ARG3 );
-   if (ARG4 != 0)
-      POST_MEM_WRITE( ARG4, sizeof(unsigned int) );
-}
-
-PRE(sys_mq_notify, 0)
-{
-   PRINT("sys_mq_notify( %d, %p )", ARG1,ARG2 );
-   PRE_REG_READ2(long, "mq_notify",
-                 vki_mqd_t, mqdes, const struct sigevent *, notification);
-   if (!VG_(fd_allowed)(ARG1, "mq_notify", tid, False))
-      SET_RESULT( -VKI_EBADF );
-   else if (ARG2 != 0)
-      PRE_MEM_READ( "mq_notify(notification)",
-                    ARG2, sizeof(struct vki_sigevent) );
-}
-
-PRE(sys_mq_getsetattr, 0)
-{
-   PRINT("sys_mq_getsetattr( %d, %p, %p )", ARG1,ARG2,ARG3 );
-   PRE_REG_READ3(long, "mq_getsetattr",
-                 vki_mqd_t, mqdes, const struct mq_attr *, mqstat,
-                 struct mq_attr *, omqstat);
-   if (!VG_(fd_allowed)(ARG1, "mq_getsetattr", tid, False)) {
-      SET_RESULT( -VKI_EBADF );
-   } else {
-      if (ARG2 != 0) {
-         const struct vki_mq_attr *attr = (struct vki_mq_attr *)ARG2;
-         PRE_MEM_READ( "mq_getsetattr(mqstat->mq_flags)",
-                        (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
-      }
-      if (ARG3 != 0)
-         PRE_MEM_WRITE( "mq_getsetattr(omqstat)", ARG3,
-                        sizeof(struct vki_mq_attr) );
-   }   
-}
-
-POST(sys_mq_getsetattr)
-{
-   if (ARG3 != 0)
-      POST_MEM_WRITE( ARG3, sizeof(struct vki_mq_attr) );
-}
-
-PRE(sys_timer_create, 0)
-{
-   PRINT("sys_timer_create( %d, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "timer_create",
-                 vki_clockid_t, clockid, struct sigevent *, evp,
-                 vki_timer_t *, timerid);
-   if (ARG2 != 0)
-      PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
-   PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
-}
-
-POST(sys_timer_create)
-{
-   POST_MEM_WRITE( ARG3, sizeof(vki_timer_t) );
-}
-
-PRE(sys_timer_settime, 0)
-{
-   PRINT("sys_timer_settime( %lld, %d, %p, %p )", (ULong)ARG1,ARG2,ARG3,ARG4);
-   PRE_REG_READ4(long, "timer_settime", 
-                 vki_timer_t, timerid, int, flags,
-                 const struct itimerspec *, value,
-                 struct itimerspec *, ovalue);
-   PRE_MEM_READ( "timer_settime(value)", ARG3,
-                  sizeof(struct vki_itimerspec) );
-   if (ARG4 != 0)
-       PRE_MEM_WRITE( "timer_settime(ovalue)", ARG4,
-                      sizeof(struct vki_itimerspec) );
-}
-
-POST(sys_timer_settime)
-{
-   if (ARG4 != 0)
-      POST_MEM_WRITE( ARG4, sizeof(struct vki_itimerspec) );
-}
-
-PRE(sys_timer_gettime, 0)
-{
-   PRINT("sys_timer_gettime( %lld, %p )", (ULong)ARG1,ARG2);
-   PRE_REG_READ2(long, "timer_gettime", 
-                 vki_timer_t, timerid, struct itimerspec *, value);
-   PRE_MEM_WRITE( "timer_gettime(value)", ARG2,
-                  sizeof(struct vki_itimerspec));
-}
-
-POST(sys_timer_gettime)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_itimerspec) );
-}
-
-PRE(sys_timer_getoverrun, 0)
-{
-   PRINT("sys_timer_getoverrun( %p )", ARG1);
-   PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t, timerid);
-}
-
-PRE(sys_timer_delete, 0)
-{
-   PRINT("sys_timer_delete( %p )", ARG1);
-   PRE_REG_READ1(long, "timer_delete", vki_timer_t, timerid);
-}
-
-PRE(sys_clock_settime, 0)
-{
-   PRINT("sys_clock_settime( %d, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "clock_settime", 
-                 vki_clockid_t, clk_id, const struct timespec *, tp);
-   PRE_MEM_READ( "clock_settime(tp)", ARG2, sizeof(struct vki_timespec) );
-}
-
-PRE(sys_clock_gettime, 0)
+PRE(sys_clock_gettime)
 {
    PRINT("sys_clock_gettime( %d, %p )" , ARG1,ARG2);
    PRE_REG_READ2(long, "clock_gettime", 
@@ -5963,250 +5568,22 @@
    POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
 }
 
-PRE(sys_clock_getres, 0)
-{
-   PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
-   // Nb: we can't use "RES" as the param name because that's a macro
-   // defined above!
-   PRE_REG_READ2(long, "clock_getres", 
-                 vki_clockid_t, clk_id, struct timespec *, res);
-   PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
-}
+//zz PRE(sys_clock_getres, 0)
+//zz {
+//zz    PRINT("sys_clock_getres( %d, %p )" , ARG1,ARG2);
+//zz    // Nb: we can't use "RES" as the param name because that's a macro
+//zz    // defined above!
+//zz    PRE_REG_READ2(long, "clock_getres", 
+//zz                  vki_clockid_t, clk_id, struct timespec *, res);
+//zz    PRE_MEM_WRITE( "clock_getres(res)", ARG2, sizeof(struct vki_timespec) );
+//zz }
+//zz 
+//zz POST(sys_clock_getres)
+//zz {
+//zz    POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
+//zz }
 
-POST(sys_clock_getres)
-{
-   POST_MEM_WRITE( ARG2, sizeof(struct vki_timespec) );
-}
-
-
-/* ---------------------------------------------------------------------
-   Executing the syscalls
-   ------------------------------------------------------------------ */
-
-static UInt bad_flags = Special;
-static void bad_before(ThreadId tid, ThreadState *tst)
-{
-   VG_(message)
-      (Vg_DebugMsg,"WARNING: unhandled syscall: %u", (UInt)SYSNO);
-   if (VG_(clo_verbosity) > 1) {
-      VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
-   }
-   VG_(message)
-      (Vg_DebugMsg,"Do not panic.  You may be able to fix this easily.");
-   VG_(message)
-      (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
-
-   SET_RESULT( -VKI_ENOSYS );
-}
-
-static const struct SyscallTableEntry bad_sys =
-   { &bad_flags, bad_before, NULL };
-
-static const struct SyscallTableEntry *get_syscall_entry(UInt syscallno)
-{
-   const struct SyscallTableEntry *sys;
-
-   if (syscallno < VGA_(syscall_table_size) &&
-       VGA_(syscall_table)[syscallno].before != NULL)
-      sys = &VGA_(syscall_table)[syscallno];
-   else
-      sys = &bad_sys;
-
-   return sys;
-}
-
-/* Perform post-syscall actions */
-void VG_(post_syscall) (ThreadId tid)
-{
-   const struct SyscallTableEntry *sys;
-   UInt flags;
-   Bool mayBlock;
-   ThreadState *tst = VG_(get_ThreadState)(tid);
-   Int syscallno;
-
-   vg_assert(VG_(is_running_thread)(tid));
-
-   syscallno = tst->syscallno;
-   tst->syscallno = -1;
-
-   vg_assert(syscallno != -1);
-
-   sys = get_syscall_entry(syscallno);
-   flags = *(sys->flags_ptr);
-
-   mayBlock        = !!( flags & MayBlock );
-
-   if (sys->after != NULL &&
-       ((flags & PostOnFail) != 0 || !VG_(is_kerror)(RES))) {
-      if (0)
-         VG_(printf)("post_syscall: calling sys_after tid=%d syscallno=%d\n",
-                     tid, syscallno);
-      (sys->after)(tid, tst);
-   }
-
-   /* Do any post-syscall actions
-
-      NOTE: this is only called if the syscall completed.  If the
-      syscall was restarted, then it will call the Tool's
-      pre_syscall again, without calling post_syscall (ie, more
-      pre's than post's) */
-   if (VG_(needs).syscall_wrapper) {
-      VG_TDICT_CALL(tool_post_syscall, tid, syscallno, RES);
-   }
-}
-
-/* Add and remove signals from mask so that we end up telling the
-   kernel the state we actually want rather than what the client
-   wants. */
-static void sanitize_client_sigmask(ThreadId tid, vki_sigset_t *mask)
-{
-   VG_(sigdelset)(mask, VKI_SIGKILL);
-   VG_(sigdelset)(mask, VKI_SIGSTOP);
-
-   VG_(sigdelset)(mask, VKI_SIGVGKILL); /* never block */
-}
-
-void VG_(client_syscall) ( ThreadId tid )
-{
-   ThreadState* tst;
-   UInt         syscallno, flags;
-   const struct SyscallTableEntry *sys;
-   Bool isSpecial    = False;
-   Bool mayBlock     = False;
-   Bool runInLWP     = False;
-   Bool syscall_done = False;	/* we actually ran the syscall */
-
-//   VGP_PUSHCC(VgpCoreSysWrap);
-
-   tst = VG_(get_ThreadState)(tid);
-
-   syscallno = (UInt)SYSNO;
-
-   /* the syscall no is in %eax.  For syscalls with <= 6 args,
-      args 1 .. 6 to the syscall are in %ebx %ecx %edx %esi %edi %ebp.
-      For calls with > 6 args, %ebx points to a lump of memory
-      containing the args.
-
-      The result is returned in %eax.  If this value >= 0, the call
-      succeeded, and this is the return value.  If < 0, it failed, and
-      the negation of this value is errno.  To be more specific, 
-      if RES is in the range -EMEDIUMTYPE (-124) .. -EPERM (-1)
-      (kernel 2.4.9 sources, include/asm-i386/errno.h)
-      then it indicates an error.  Otherwise it doesn't.
-
-      Dirk Mueller (mueller@kde.org) says that values -4095 .. -1
-      (inclusive?) indicate error returns.  Not sure where the -4095
-      comes from.
-   */
-
-   vg_assert(VG_(is_running_thread)(tid));
-   vg_assert(tst->syscallno == -1);
-   tst->syscallno = syscallno;
-
-   /* Make sure the tmp signal mask matches the real signal
-      mask; sigsuspend may change this. */
-   vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
-
-   sys = get_syscall_entry(syscallno);
-   flags = *(sys->flags_ptr);
-
-   /* !! is standard idiom to turn an int->bool */
-   isSpecial       = !!( flags & Special );
-   mayBlock        = !!( flags & MayBlock );
-   // At most one of these should be true
-   vg_assert( isSpecial + mayBlock <= 1 );
-
-   /* Do any pre-syscall actions */
-   if (VG_(needs).syscall_wrapper) {
-      VG_TDICT_CALL(tool_pre_syscall, tid, syscallno);
-   }
-
-   PRINT("SYSCALL[%d,%d](%3d)%s%s:", 
-         VG_(getpid)(), tid, syscallno, 
-         isSpecial ? " special"  : "",
-         runInLWP  ? " runInLWP" : "");
-
-   tst->syscall_result_set = False;
-
-   if (isSpecial) {
-      /* "Special" syscalls are implemented by Valgrind internally,
-	 and do not generate real kernel calls.  The expectation,
-	 therefore, is that the "before" function not only does the
-	 appropriate tests, but also performs the syscall itself and
-	 sets the result.  Special syscalls cannot block. */
-      vg_assert(!mayBlock && !runInLWP);
-
-      (sys->before)(tst->tid, tst);
-      /* This *must* result in tst->syscall_result_set becoming
-         True. */
-
-      //      vg_assert(tst->sys_flags == flags);
-      vg_assert(tst->syscall_result_set == True);
-
-      PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
-      syscall_done = True;
-   } else {
-      (sys->before)(tst->tid, tst);
-      /* This *may* result in tst->syscall_result_set becoming
-         True. */
-
-      if (tst->syscall_result_set) {
-	 /* "before" decided to provide a syscall result itself, so
-	    don't do anything - just pretend the syscall happened. */
-         PRINT(" ==> %lld (0x%llx)\n", (Long)RES, (ULong)RES);
-	 syscall_done = True;
-      } else if (mayBlock) {
-         vki_sigset_t mask;
-
-         vg_assert(!(flags & PadAddr));
-
-         /* Syscall may block, so run it asynchronously */
-         PRINT(" --> ...\n");
-
-         mask = tst->sig_mask;
-         sanitize_client_sigmask(tid, &mask);
-
-         VG_(set_sleeping)(tid, VgTs_WaitSys);
-         VGA_(client_syscall)(syscallno, tst, &mask);
-         /* VGA_(client_syscall) may not return if the syscall was
-            interrupted by a signal.  In that case, flow of control
-            will end up back in the scheduler via the signal
-            machinery. */
-         VG_(set_running)(tid);
-         PRINT("SYSCALL[%d,%d](%3d) --> %lld (0x%llx)\n",
-               VG_(getpid)(), tid, syscallno, (Long)(Word)RES, (ULong)RES);
-      } else {
-	 /* run the syscall directly */
-         if (flags & PadAddr)
-            VG_(pad_address_space)(VG_(client_end));
-
-	 RES = VG_(do_syscall6)(syscallno, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
-         PRINT(" --> %lld (0x%llx)\n", (Long)(Word)RES, (ULong)RES);
-	 syscall_done = True;
-      }
-   }
-
-   vg_assert(VG_(is_running_thread)(tid));
-
-   // Tell the tool that the assignment has occurred, so it can update
-   // shadow regs as necessary.
-   VGP_TRACK_SYSCALL_RETVAL(tid);
-
-   VG_(post_syscall)(tid);
-
-   if (flags & PadAddr) {
-      vg_assert(!mayBlock);
-      VG_(unpad_address_space)(VG_(client_end));
-      //VG_(sanity_check_memory)();
-   }
-
-   /* VG_(post_syscall) should set this */
-   vg_assert(tst->syscallno == -1);
-
-//   VGP_POPCC(VgpCoreSysWrap);
-}
 
 /*--------------------------------------------------------------------*/
-/*--- end                                                          ---*/
+/*--- end                                       syscalls-generic.c ---*/
 /*--------------------------------------------------------------------*/
-
diff --git a/coregrind/m_syscalls/syscalls-linux.c b/coregrind/m_syscalls/syscalls-linux.c
index 2d801a1..c8f3bfc 100644
--- a/coregrind/m_syscalls/syscalls-linux.c
+++ b/coregrind/m_syscalls/syscalls-linux.c
@@ -34,7 +34,11 @@
 #include "pub_core_libcfile.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_tooliface.h"
-#include "priv_syscalls.h"
+#include "pub_core_options.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-linux.h"
+
 
 /* ---------------------------------------------------------------------
    PRE/POST wrappers for arch-generic, Linux-specific syscalls
@@ -43,22 +47,29 @@
 // Nb: See the comment above the generic PRE/POST wrappers in
 // coregrind/vg_syscalls.c for notes about how they work.
 
-#define PRE(name, f)     PRE_TEMPLATE( , vgOS_linux, name, f)
-#define POST(name)      POST_TEMPLATE( , vgOS_linux, name)
+#define PRE(name)       DEFN_PRE_TEMPLATE(linux, name)
+#define POST(name)      DEFN_POST_TEMPLATE(linux, name)
 
-PRE(sys_exit_group, Special)
+PRE(sys_exit_group)
 {
-   ThreadId t;
+   ThreadId     t;
+   ThreadState* tst;
 
    PRINT("exit_group( %d )", ARG1);
    PRE_REG_READ1(void, "exit_group", int, exit_code);
 
+   tst = VG_(get_ThreadState)(tid);
+
    /* A little complex; find all the threads with the same threadgroup
       as this one (including this one), and mark them to exit */
    for (t = 1; t < VG_N_THREADS; t++) {
-      if (VG_(threads)[t].status == VgTs_Empty ||				/* not alive */
-	  VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup)	/* not our group */
-	 continue;
+      if ( /* not alive */
+           VG_(threads)[t].status == VgTs_Empty 
+           ||
+	   /* not our group */
+           VG_(threads)[t].os_state.threadgroup != tst->os_state.threadgroup
+         )
+         continue;
 
       VG_(threads)[t].exitreason = VgSrc_ExitSyscall;
       VG_(threads)[t].os_state.exitcode = ARG1;
@@ -67,19 +78,16 @@
 	 VG_(kill_thread)(t);	/* unblock it, if blocked */
    }
 
-   /* exit_group doesn't return anything (perhaps it doesn't return?)
-      Nevertheless, if we don't do this, the result-not-assigned-
-      yet-you-said-you-were-Special assertion in the main syscall
-      handling logic will fire.  Hence ..
-   */
-   SET_RESULT(0);
+   /* We have to claim the syscall already succeeded. */
+   SET_STATUS_Success(0);
 }
 
-PRE(sys_mount, MayBlock)
+PRE(sys_mount)
 {
    // Nb: depending on 'flags', the 'type' and 'data' args may be ignored.
    // We are conservative and check everything, except the memory pointed to
    // by 'data'.
+   *flags |= SfMayBlock;
    PRINT( "sys_mount( %p, %p, %p, %p, %p )" ,ARG1,ARG2,ARG3,ARG4,ARG5);
    PRE_REG_READ5(long, "mount",
                  char *, source, char *, target, char *, type,
@@ -89,21 +97,21 @@
    PRE_MEM_RASCIIZ( "mount(type)", ARG3);
 }
 
-PRE(sys_oldumount, 0)
+PRE(sys_oldumount)
 {
    PRINT("sys_oldumount( %p )", ARG1);
    PRE_REG_READ1(long, "umount", char *, path);
    PRE_MEM_RASCIIZ( "umount(path)", ARG1);
 }
 
-PRE(sys_umount, 0)
+PRE(sys_umount)
 {
    PRINT("sys_umount( %p )", ARG1);
    PRE_REG_READ2(long, "umount2", char *, path, int, flags);
    PRE_MEM_RASCIIZ( "umount2(path)", ARG1);
 }
 
-PRE(sys_llseek, 0)
+PRE(sys_llseek)
 {
    PRINT("sys_llseek ( %d, 0x%x, 0x%x, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5);
    PRE_REG_READ5(long, "llseek",
@@ -115,641 +123,642 @@
 
 POST(sys_llseek)
 {
+   vg_assert(SUCCESS);
    if (RES == 0)
       POST_MEM_WRITE( ARG4, sizeof(vki_loff_t) );
 }
 
-PRE(sys_adjtimex, 0)
-{
-   struct vki_timex *tx = (struct vki_timex *)ARG1;
-   PRINT("sys_adjtimex ( %p )", ARG1);
-   PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
-   PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
+//zz PRE(sys_adjtimex, 0)
+//zz {
+//zz    struct vki_timex *tx = (struct vki_timex *)ARG1;
+//zz    PRINT("sys_adjtimex ( %p )", ARG1);
+//zz    PRE_REG_READ1(long, "adjtimex", struct timex *, buf);
+//zz    PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes));
+//zz 
+//zz #define ADJX(bit,field) 				\
+//zz    if (tx->modes & bit)					\
+//zz       PRE_MEM_READ( "adjtimex(timex->"#field")",	\
+//zz 		    (Addr)&tx->field, sizeof(tx->field))
+//zz    ADJX(ADJ_FREQUENCY, freq);
+//zz    ADJX(ADJ_MAXERROR, maxerror);
+//zz    ADJX(ADJ_ESTERROR, esterror);
+//zz    ADJX(ADJ_STATUS, status);
+//zz    ADJX(ADJ_TIMECONST, constant);
+//zz    ADJX(ADJ_TICK, tick);
+//zz #undef ADJX
+//zz    
+//zz    PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
+//zz }
+//zz 
+//zz POST(sys_adjtimex)
+//zz {
+//zz    POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
+//zz }
+//zz 
+//zz PRE(sys_setfsuid16, 0)
+//zz {
+//zz    PRINT("sys_setfsuid16 ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
+//zz }
+//zz 
+//zz PRE(sys_setfsuid, 0)
+//zz {
+//zz    PRINT("sys_setfsuid ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
+//zz }
+//zz 
+//zz PRE(sys_setfsgid16, 0)
+//zz {
+//zz    PRINT("sys_setfsgid16 ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
+//zz }
+//zz 
+//zz PRE(sys_setfsgid, 0)
+//zz {
+//zz    PRINT("sys_setfsgid ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
+//zz }
+//zz 
+//zz PRE(sys_setresuid16, 0)
+//zz {
+//zz    PRINT("sys_setresuid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "setresuid16",
+//zz                  vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
+//zz }
+//zz 
+//zz PRE(sys_setresuid, 0)
+//zz {
+//zz    PRINT("sys_setresuid ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "setresuid",
+//zz                  vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
+//zz }
+//zz 
+//zz PRE(sys_getresuid16, 0)
+//zz {
+//zz    PRINT("sys_getresuid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "getresuid16",
+//zz                  vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
+//zz                  vki_old_uid_t *, suid);
+//zz    PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
+//zz    PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
+//zz    PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
+//zz }
+//zz 
+//zz POST(sys_getresuid16)
+//zz {
+//zz    if (RES == 0) {
+//zz       POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
+//zz       POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
+//zz       POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_getresuid, 0)
+//zz {
+//zz    PRINT("sys_getresuid ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "getresuid", 
+//zz                  vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
+//zz    PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
+//zz    PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
+//zz    PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
+//zz }
+//zz 
+//zz POST(sys_getresuid)
+//zz {
+//zz    if (RES == 0) {
+//zz       POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
+//zz       POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
+//zz       POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_setresgid16, 0)
+//zz {
+//zz    PRINT("sys_setresgid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "setresgid16",
+//zz                  vki_old_gid_t, rgid, vki_old_gid_t, egid, vki_old_gid_t, sgid);
+//zz }
+//zz 
+//zz PRE(sys_setresgid, 0)
+//zz {
+//zz    PRINT("sys_setresgid ( %d, %d, %d )", ARG1, ARG2, ARG3);
+//zz    PRE_REG_READ3(long, "setresgid",
+//zz                  vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
+//zz }
+//zz 
+//zz PRE(sys_getresgid16, 0)
+//zz {
+//zz    PRINT("sys_getresgid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "getresgid16",
+//zz                  vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
+//zz                  vki_old_gid_t *, sgid);
+//zz    PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
+//zz    PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
+//zz    PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
+//zz }
+//zz 
+//zz POST(sys_getresgid16)
+//zz {
+//zz    if (RES == 0) {
+//zz       POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
+//zz       POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
+//zz       POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_getresgid, 0)
+//zz {
+//zz    PRINT("sys_getresgid ( %p, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "getresgid", 
+//zz                  vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
+//zz    PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
+//zz    PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
+//zz    PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
+//zz }
+//zz 
+//zz POST(sys_getresgid)
+//zz {
+//zz    if (RES == 0) {
+//zz       POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
+//zz       POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
+//zz       POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_ioperm, 0)
+//zz {
+//zz    PRINT("sys_ioperm ( %d, %d, %d )", ARG1, ARG2, ARG3 );
+//zz    PRE_REG_READ3(long, "ioperm",
+//zz                  unsigned long, from, unsigned long, num, int, turn_on);
+//zz }
+//zz 
+//zz PRE(sys_syslog, MayBlock)
+//zz {
+//zz    PRINT("sys_syslog (%d, %p, %d)", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
+//zz    switch (ARG1) {
+//zz    // The kernel uses magic numbers here, rather than named constants,
+//zz    // therefore so do we.
+//zz    case 2: case 3: case 4:
+//zz       PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
+//zz       break;
+//zz    default: 
+//zz       break;
+//zz    }
+//zz }
+//zz 
+//zz POST(sys_syslog)
+//zz {
+//zz    switch (ARG1) {
+//zz    case 2: case 3: case 4:
+//zz       POST_MEM_WRITE( ARG2, ARG3 );
+//zz       break;
+//zz    default:
+//zz       break;
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_vhangup, 0)
+//zz {
+//zz    PRINT("sys_vhangup ( )");
+//zz    PRE_REG_READ0(long, "vhangup");
+//zz }
+//zz 
+//zz PRE(sys_sysinfo, 0)
+//zz {
+//zz    PRINT("sys_sysinfo ( %p )",ARG1);
+//zz    PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
+//zz    PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
+//zz }
+//zz 
+//zz POST(sys_sysinfo)
+//zz {
+//zz    POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
+//zz }
+//zz 
+//zz PRE(sys_personality, 0)
+//zz {
+//zz    PRINT("sys_personality ( %llu )", (ULong)ARG1);
+//zz    PRE_REG_READ1(long, "personality", vki_u_long, persona);
+//zz }
 
-#define ADJX(bit,field) 				\
-   if (tx->modes & bit)					\
-      PRE_MEM_READ( "adjtimex(timex->"#field")",	\
-		    (Addr)&tx->field, sizeof(tx->field))
-   ADJX(ADJ_FREQUENCY, freq);
-   ADJX(ADJ_MAXERROR, maxerror);
-   ADJX(ADJ_ESTERROR, esterror);
-   ADJX(ADJ_STATUS, status);
-   ADJX(ADJ_TIMECONST, constant);
-   ADJX(ADJ_TICK, tick);
-#undef ADJX
-   
-   PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex));
-}
-
-POST(sys_adjtimex)
+PRE(sys_sysctl)
 {
-   POST_MEM_WRITE( ARG1, sizeof(struct vki_timex) );
-}
-
-PRE(sys_setfsuid16, 0)
-{
-   PRINT("sys_setfsuid16 ( %d )", ARG1);
-   PRE_REG_READ1(long, "setfsuid16", vki_old_uid_t, uid);
-}
-
-PRE(sys_setfsuid, 0)
-{
-   PRINT("sys_setfsuid ( %d )", ARG1);
-   PRE_REG_READ1(long, "setfsuid", vki_uid_t, uid);
-}
-
-PRE(sys_setfsgid16, 0)
-{
-   PRINT("sys_setfsgid16 ( %d )", ARG1);
-   PRE_REG_READ1(long, "setfsgid16", vki_old_gid_t, gid);
-}
-
-PRE(sys_setfsgid, 0)
-{
-   PRINT("sys_setfsgid ( %d )", ARG1);
-   PRE_REG_READ1(long, "setfsgid", vki_gid_t, gid);
-}
-
-PRE(sys_setresuid16, 0)
-{
-   PRINT("sys_setresuid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "setresuid16",
-                 vki_old_uid_t, ruid, vki_old_uid_t, euid, vki_old_uid_t, suid);
-}
-
-PRE(sys_setresuid, 0)
-{
-   PRINT("sys_setresuid ( %d, %d, %d )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "setresuid",
-                 vki_uid_t, ruid, vki_uid_t, euid, vki_uid_t, suid);
-}
-
-PRE(sys_getresuid16, 0)
-{
-   PRINT("sys_getresuid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "getresuid16",
-                 vki_old_uid_t *, ruid, vki_old_uid_t *, euid,
-                 vki_old_uid_t *, suid);
-   PRE_MEM_WRITE( "getresuid16(ruid)", ARG1, sizeof(vki_old_uid_t) );
-   PRE_MEM_WRITE( "getresuid16(euid)", ARG2, sizeof(vki_old_uid_t) );
-   PRE_MEM_WRITE( "getresuid16(suid)", ARG3, sizeof(vki_old_uid_t) );
-}
-
-POST(sys_getresuid16)
-{
-   if (RES == 0) {
-      POST_MEM_WRITE( ARG1, sizeof(vki_old_uid_t) );
-      POST_MEM_WRITE( ARG2, sizeof(vki_old_uid_t) );
-      POST_MEM_WRITE( ARG3, sizeof(vki_old_uid_t) );
-   }
-}
-
-PRE(sys_getresuid, 0)
-{
-   PRINT("sys_getresuid ( %p, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "getresuid", 
-                 vki_uid_t *, ruid, vki_uid_t *, euid, vki_uid_t *, suid);
-   PRE_MEM_WRITE( "getresuid(ruid)", ARG1, sizeof(vki_uid_t) );
-   PRE_MEM_WRITE( "getresuid(euid)", ARG2, sizeof(vki_uid_t) );
-   PRE_MEM_WRITE( "getresuid(suid)", ARG3, sizeof(vki_uid_t) );
-}
-
-POST(sys_getresuid)
-{
-   if (RES == 0) {
-      POST_MEM_WRITE( ARG1, sizeof(vki_uid_t) );
-      POST_MEM_WRITE( ARG2, sizeof(vki_uid_t) );
-      POST_MEM_WRITE( ARG3, sizeof(vki_uid_t) );
-   }
-}
-
-PRE(sys_setresgid16, 0)
-{
-   PRINT("sys_setresgid16 ( %d, %d, %d )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "setresgid16",
-                 vki_old_gid_t, rgid, vki_old_gid_t, egid, vki_old_gid_t, sgid);
-}
-
-PRE(sys_setresgid, 0)
-{
-   PRINT("sys_setresgid ( %d, %d, %d )", ARG1, ARG2, ARG3);
-   PRE_REG_READ3(long, "setresgid",
-                 vki_gid_t, rgid, vki_gid_t, egid, vki_gid_t, sgid);
-}
-
-PRE(sys_getresgid16, 0)
-{
-   PRINT("sys_getresgid16 ( %p, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "getresgid16",
-                 vki_old_gid_t *, rgid, vki_old_gid_t *, egid,
-                 vki_old_gid_t *, sgid);
-   PRE_MEM_WRITE( "getresgid16(rgid)", ARG1, sizeof(vki_old_gid_t) );
-   PRE_MEM_WRITE( "getresgid16(egid)", ARG2, sizeof(vki_old_gid_t) );
-   PRE_MEM_WRITE( "getresgid16(sgid)", ARG3, sizeof(vki_old_gid_t) );
-}
-
-POST(sys_getresgid16)
-{
-   if (RES == 0) {
-      POST_MEM_WRITE( ARG1, sizeof(vki_old_gid_t) );
-      POST_MEM_WRITE( ARG2, sizeof(vki_old_gid_t) );
-      POST_MEM_WRITE( ARG3, sizeof(vki_old_gid_t) );
-   }
-}
-
-PRE(sys_getresgid, 0)
-{
-   PRINT("sys_getresgid ( %p, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "getresgid", 
-                 vki_gid_t *, rgid, vki_gid_t *, egid, vki_gid_t *, sgid);
-   PRE_MEM_WRITE( "getresgid(rgid)", ARG1, sizeof(vki_gid_t) );
-   PRE_MEM_WRITE( "getresgid(egid)", ARG2, sizeof(vki_gid_t) );
-   PRE_MEM_WRITE( "getresgid(sgid)", ARG3, sizeof(vki_gid_t) );
-}
-
-POST(sys_getresgid)
-{
-   if (RES == 0) {
-      POST_MEM_WRITE( ARG1, sizeof(vki_gid_t) );
-      POST_MEM_WRITE( ARG2, sizeof(vki_gid_t) );
-      POST_MEM_WRITE( ARG3, sizeof(vki_gid_t) );
-   }
-}
-
-PRE(sys_ioperm, 0)
-{
-   PRINT("sys_ioperm ( %d, %d, %d )", ARG1, ARG2, ARG3 );
-   PRE_REG_READ3(long, "ioperm",
-                 unsigned long, from, unsigned long, num, int, turn_on);
-}
-
-PRE(sys_syslog, MayBlock)
-{
-   PRINT("sys_syslog (%d, %p, %d)", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "syslog", int, type, char *, bufp, int, len);
-   switch (ARG1) {
-   // The kernel uses magic numbers here, rather than named constants,
-   // therefore so do we.
-   case 2: case 3: case 4:
-      PRE_MEM_WRITE( "syslog(bufp)", ARG2, ARG3);
-      break;
-   default: 
-      break;
-   }
-}
-
-POST(sys_syslog)
-{
-   switch (ARG1) {
-   case 2: case 3: case 4:
-      POST_MEM_WRITE( ARG2, ARG3 );
-      break;
-   default:
-      break;
-   }
-}
-
-PRE(sys_vhangup, 0)
-{
-   PRINT("sys_vhangup ( )");
-   PRE_REG_READ0(long, "vhangup");
-}
-
-PRE(sys_sysinfo, 0)
-{
-   PRINT("sys_sysinfo ( %p )",ARG1);
-   PRE_REG_READ1(long, "sysinfo", struct sysinfo *, info);
-   PRE_MEM_WRITE( "sysinfo(info)", ARG1, sizeof(struct vki_sysinfo) );
-}
-
-POST(sys_sysinfo)
-{
-   POST_MEM_WRITE( ARG1, sizeof(struct vki_sysinfo) );
-}
-
-PRE(sys_personality, 0)
-{
-   PRINT("sys_personality ( %llu )", (ULong)ARG1);
-   PRE_REG_READ1(long, "personality", vki_u_long, persona);
-}
-
-PRE(sys_sysctl, 0)
-{
-   struct __vki_sysctl_args *args;
+   struct __vki_sysctl_args *argz;
    PRINT("sys_sysctl ( %p )", ARG1 );
-   args = (struct __vki_sysctl_args *)ARG1;
-   PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, args);
+   argz = (struct __vki_sysctl_args *)ARG1;
+   PRE_REG_READ1(long, "sysctl", struct __sysctl_args *, argz);
    PRE_MEM_WRITE( "sysctl(args)", ARG1, sizeof(struct __vki_sysctl_args) );
    if (!VG_(is_addressable)(ARG1, sizeof(struct __vki_sysctl_args), VKI_PROT_READ)) {
-      SET_RESULT( -VKI_EFAULT );
+      SET_STATUS_Failure( VKI_EFAULT );
       return;
    }
 
-   PRE_MEM_READ("sysctl(name)", (Addr)args->name, args->nlen * sizeof(*args->name));
-   if (args->newval != NULL)
-      PRE_MEM_READ("sysctl(newval)", (Addr)args->newval, args->newlen);
-   if (args->oldlenp != NULL) {
-      PRE_MEM_READ("sysctl(oldlenp)", (Addr)args->oldlenp, sizeof(*args->oldlenp));
-      PRE_MEM_WRITE("sysctl(oldval)", (Addr)args->oldval, *args->oldlenp);
+   PRE_MEM_READ("sysctl(name)", (Addr)argz->name, argz->nlen * sizeof(*argz->name));
+   if (argz->newval != NULL)
+      PRE_MEM_READ("sysctl(newval)", (Addr)argz->newval, argz->newlen);
+   if (argz->oldlenp != NULL) {
+      PRE_MEM_READ("sysctl(oldlenp)", (Addr)argz->oldlenp, sizeof(*argz->oldlenp));
+      PRE_MEM_WRITE("sysctl(oldval)", (Addr)argz->oldval, *argz->oldlenp);
    }
 }
 
 POST(sys_sysctl)
 {
-   struct __vki_sysctl_args *args;
-   args = (struct __vki_sysctl_args *)ARG1;
-   if (args->oldlenp != NULL) {
-      POST_MEM_WRITE((Addr)args->oldlenp, sizeof(*args->oldlenp));
-      POST_MEM_WRITE((Addr)args->oldval, 1 + *args->oldlenp);
+   struct __vki_sysctl_args *argz;
+   argz = (struct __vki_sysctl_args *)ARG1;
+   if (argz->oldlenp != NULL) {
+      POST_MEM_WRITE((Addr)argz->oldlenp, sizeof(*argz->oldlenp));
+      POST_MEM_WRITE((Addr)argz->oldval, 1 + *argz->oldlenp);
    }
 }
 
-PRE(sys_prctl, MayBlock)
-{
-   PRINT( "prctl ( %d, %d, %d, %d, %d )", ARG1, ARG2, ARG3, ARG4, ARG5 );
-   // XXX: too simplistic, often not all args are used
-   // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
-   PRE_REG_READ5(long, "prctl",
-                 int, option, unsigned long, arg2, unsigned long, arg3,
-                 unsigned long, arg4, unsigned long, arg5);
-   // XXX: totally wrong... we need to look at the 'option' arg, and do
-   // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
-}
-
-PRE(sys_sendfile, MayBlock)
-{
-   PRINT("sys_sendfile ( %d, %d, %p, %llu )", ARG1,ARG2,ARG3,(ULong)ARG4);
-   PRE_REG_READ4(ssize_t, "sendfile",
-                 int, out_fd, int, in_fd, vki_off_t *, offset,
-                 vki_size_t, count);
-   if (ARG3 != 0)
-      PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
-}
-
-POST(sys_sendfile)
-{
-   POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
-}
-
-PRE(sys_sendfile64, MayBlock)
-{
-   PRINT("sendfile64 ( %d, %d, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
-   PRE_REG_READ4(ssize_t, "sendfile64",
-                 int, out_fd, int, in_fd, vki_loff_t *, offset,
-                 vki_size_t, count);
-   if (ARG3 != 0)
-      PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
-}
-
-POST(sys_sendfile64)
-{
-   if (ARG3 != 0 ) {
-      POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
-   }
-}
-
-PRE(sys_futex, MayBlock)
-{
-   /* 
-      arg    param                              used by ops
-
-      ARG1 - u32 *futex				all
-      ARG2 - int op
-      ARG3 - int val				WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
-      ARG4 - struct timespec *utime		WAIT:time*	REQUEUE,CMP_REQUEUE:val2
-      ARG5 - u32 *uaddr2			REQUEUE,CMP_REQUEUE
-      ARG6 - int val3				CMP_REQUEUE
-    */
-   PRINT("sys_futex ( %p, %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
-   PRE_REG_READ6(long, "futex", 
-                 vki_u32 *, futex, int, op, int, val,
-                 struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
-
-   PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
-
-   switch(ARG2) {
-   case VKI_FUTEX_WAIT:
-      if (ARG4 != 0)
-	 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
-      break;
-
-   case VKI_FUTEX_REQUEUE:
-   case VKI_FUTEX_CMP_REQUEUE:
-      PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
-      break;
-
-   case VKI_FUTEX_WAKE:
-   case VKI_FUTEX_FD:
-      /* no additional pointers */
-      break;
-
-   default:
-      SET_RESULT(-VKI_ENOSYS);   // some futex function we don't understand
-      break;
-   }
-}
-
-POST(sys_futex)
-{
-   POST_MEM_WRITE( ARG1, sizeof(int) );
-   if (ARG2 == VKI_FUTEX_FD) {
-      if (!VG_(fd_allowed)(RES, "futex", tid, True)) {
-         VG_(close)(RES);
-         SET_RESULT( -VKI_EMFILE );
-      } else {
-         if (VG_(clo_track_fds))
-            VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
-      }
-   }
-}
-
-PRE(sys_epoll_create, 0)
-{
-   PRINT("sys_epoll_create ( %d )", ARG1);
-   PRE_REG_READ1(long, "epoll_create", int, size);
-}
-
-POST(sys_epoll_create)
-{
-   if (!VG_(fd_allowed)(RES, "epoll_create", tid, True)) {
-      VG_(close)(RES);
-      SET_RESULT( -VKI_EMFILE );
-   } else {
-      if (VG_(clo_track_fds))
-         VG_(record_fd_open) (tid, RES, NULL);
-   }
-}
-
-PRE(sys_epoll_ctl, 0)
-{
-   static const char* epoll_ctl_s[3] = {
-      "EPOLL_CTL_ADD",
-      "EPOLL_CTL_DEL",
-      "EPOLL_CTL_MOD"
-   };
-   PRINT("sys_epoll_ctl ( %d, %s, %d, %p )", 
-         ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
-   PRE_REG_READ4(long, "epoll_ctl",
-                 int, epfd, int, op, int, fd, struct epoll_event *, event);
-   PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct epoll_event) );
-}
-
-PRE(sys_epoll_wait, MayBlock)
-{
-   PRINT("sys_epoll_wait ( %d, %p, %d, %d )", ARG1, ARG2, ARG3, ARG4);
-   PRE_REG_READ4(long, "epoll_wait",
-                 int, epfd, struct epoll_event *, events,
-                 int, maxevents, int, timeout);
-   PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct epoll_event)*ARG3);
-}
-
-POST(sys_epoll_wait)
-{
-   if (RES > 0)
-      POST_MEM_WRITE( ARG2, sizeof(struct epoll_event)*RES ) ;
-}
-
-PRE(sys_gettid, 0)
-{
-   PRINT("sys_gettid ()");
-   PRE_REG_READ0(long, "gettid");
-}
-
-PRE(sys_tkill, Special)
-{
-   /* int tkill(pid_t tid, int sig); */
-   PRINT("sys_tkill ( %d, %d )", ARG1,ARG2);
-   PRE_REG_READ2(long, "tkill", int, tid, int, sig);
-   if (!VG_(client_signal_OK)(ARG2)) {
-      SET_RESULT( -VKI_EINVAL );
-      return;
-   }
-
-   /* If we're sending SIGKILL, check to see if the target is one of
-      our threads and handle it specially. */
-   if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
-      SET_RESULT(0);
-   else
-      SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
-
-   if (VG_(clo_trace_signals))
-      VG_(message)(Vg_DebugMsg, "tkill: sent signal %d to pid %d",
-		   ARG2, ARG1);
-   // Check to see if this kill gave us a pending signal
-   VG_(poll_signals)(tid);
-}
-
-PRE(sys_tgkill, Special)
-{
-   /* int tgkill(pid_t tgid, pid_t tid, int sig); */
-   PRINT("sys_tgkill ( %d, %d, %d )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
-   if (!VG_(client_signal_OK)(ARG3)) {
-      SET_RESULT( -VKI_EINVAL );
-      return;
-   }
-   
-   /* If we're sending SIGKILL, check to see if the target is one of
-      our threads and handle it specially. */
-   if (ARG3 == VKI_SIGKILL && VG_(do_sigkill)(ARG2, ARG1))
-      SET_RESULT(0);
-   else
-      SET_RESULT(VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3));
-
-   if (VG_(clo_trace_signals))
-      VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
-		   ARG3, ARG1, ARG2);
-   // Check to see if this kill gave us a pending signal
-   VG_(poll_signals)(tid);
-}
-
-POST(sys_tgkill)
-{
-   if (VG_(clo_trace_signals))
-      VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
-                   ARG3, ARG1, ARG2);
-   // Check to see if this kill gave us a pending signal
-   VG_(poll_signals)(tid);
-}
-
-PRE(sys_fadvise64, 0)
-{
-   PRINT("sys_fadvise64 ( %d, %lld, %lu, %d )", ARG1,ARG2,ARG3);
-   PRE_REG_READ4(long, "fadvise64",
-                 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice)
-}
-
-PRE(sys_fadvise64_64, 0)
-{
-   PRINT("sys_fadvise64_64 ( %d, %lld, %lld, %d )", ARG1,ARG2,ARG3);
-   PRE_REG_READ4(long, "fadvise64_64",
-                 int, fd, vki_loff_t, offset, vki_loff_t, len, int, advice)
-}
-
-// Nb: this wrapper is "Special" because we have to pad/unpad memory around
-// the syscall itself, and this allows us to control exactly the code that
-// gets run while the padding is in place.
-PRE(sys_io_setup, Special)
-{
-   SizeT size;
-   Addr addr;
-
-   PRINT("sys_io_setup ( %u, %p )", ARG1,ARG2);
-   PRE_REG_READ2(long, "io_setup",
-                 unsigned, nr_events, vki_aio_context_t *, ctxp);
-   PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
-   
-   size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
-                       ARG1*sizeof(struct vki_io_event));
-   addr = VG_(find_map_space)(0, size, True);
-   
-   if (addr == 0) {
-      SET_RESULT( -VKI_ENOMEM );
-      return;
-   }
-
-   VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, SF_FIXED);
-   
-   VG_(pad_address_space)(0);
-   SET_RESULT( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
-   VG_(unpad_address_space)(0);
-
-   if (RES == 0) {
-      struct vki_aio_ring *r = *(struct vki_aio_ring **)ARG2;
-        
-      vg_assert(addr == (Addr)r);
-      vg_assert(VG_(valid_client_addr)(addr, size, tid, "io_setup"));
-                
-      VG_TRACK( new_mem_mmap, addr, size, True, True, False );
-      POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
-   }
-   else {
-      VG_(unmap_range)(addr, size);
-   }
-}
-
-// Nb: This wrapper is "Special" because we need 'size' to do the unmap
-// after the syscall.  We must get 'size' from the aio_ring structure,
-// before the syscall, while the aio_ring structure still exists.  (And we
-// know that we must look at the aio_ring structure because Tom inspected the
-// kernel and glibc sources to see what they do, yuk.)
-//
-// XXX This segment can be implicitly unmapped when aio
-// file-descriptors are closed...
-PRE(sys_io_destroy, Special)
-{     
-   Segment *s = VG_(find_segment)(ARG1);
-   struct vki_aio_ring *r;
-   SizeT size;
-      
-   PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
-   PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
-
-   // If we are going to seg fault (due to a bogus ARG1) do it as late as
-   // possible...
-   r = *(struct vki_aio_ring **)ARG1;
-   size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) + 
-                       r->nr*sizeof(struct vki_io_event));
-
-   SET_RESULT( VG_(do_syscall1)(SYSNO, ARG1) );
-
-   if (RES == 0 && s != NULL) { 
-      VG_TRACK( die_mem_munmap, ARG1, size );
-      VG_(unmap_range)(ARG1, size);
-   }  
-}  
-
-PRE(sys_io_getevents, MayBlock)
-{
-   PRINT("sys_io_getevents ( %llu, %lld, %lld, %p, %p )",
-         (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
-   PRE_REG_READ5(long, "io_getevents",
-                 vki_aio_context_t, ctx_id, long, min_nr, long, nr,
-                 struct io_event *, events,
-                 struct timespec *, timeout);
-   if (ARG3 > 0)
-      PRE_MEM_WRITE( "io_getevents(events)",
-                     ARG4, sizeof(struct vki_io_event)*ARG3 );
-   if (ARG5 != 0)
-      PRE_MEM_READ( "io_getevents(timeout)",
-                    ARG5, sizeof(struct vki_timespec));
-}
-
-POST(sys_io_getevents)
-{
-   int i;
-
-   if (RES > 0) {
-      POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
-      for (i = 0; i < RES; i++) {
-         const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
-         const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
-
-         switch (cb->aio_lio_opcode) {
-         case VKI_IOCB_CMD_PREAD:
-            if (vev->result > 0)
-               POST_MEM_WRITE( cb->aio_buf, vev->result );
-            break;
-            
-         case VKI_IOCB_CMD_PWRITE:
-            break;
-           
-         default:
-            VG_(message)(Vg_DebugMsg,"Warning: unhandled io_getevents opcode: %u\n",cb->aio_lio_opcode);
-            break;
-         }
-      }
-   }
-}
-
-PRE(sys_io_submit, 0)
-{
-   int i;
-
-   PRINT("sys_io_submit( %llu, %lld, %p )", (ULong)ARG1,(Long)ARG2,ARG3);
-   PRE_REG_READ3(long, "io_submit",
-                 vki_aio_context_t, ctx_id, long, nr,
-                 struct iocb **, iocbpp);
-   PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
-   if (ARG3 != 0) {
-      for (i = 0; i < ARG2; i++) {
-         struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
-         PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
-         switch (cb->aio_lio_opcode) {
-         case VKI_IOCB_CMD_PREAD:
-            PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
-            break;
-
-         case VKI_IOCB_CMD_PWRITE:
-            PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
-            break;
-           
-         default:
-            VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
-                         cb->aio_lio_opcode);
-            break;
-         }
-      }
-   }
-}
-
-PRE(sys_io_cancel, 0)
-{
-   PRINT("sys_io_cancel( %llu, %p, %p )", (ULong)ARG1,ARG2,ARG3);
-   PRE_REG_READ3(long, "io_cancel",
-                 vki_aio_context_t, ctx_id, struct iocb *, iocb,
-                 struct io_event *, result);
-   PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
-   PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
-}
-
-POST(sys_io_cancel)
-{
-   POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
-}
-
-#undef PRE
-#undef POST
+//zz PRE(sys_prctl, MayBlock)
+//zz {
+//zz    PRINT( "prctl ( %d, %d, %d, %d, %d )", ARG1, ARG2, ARG3, ARG4, ARG5 );
+//zz    // XXX: too simplistic, often not all args are used
+//zz    // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
+//zz    PRE_REG_READ5(long, "prctl",
+//zz                  int, option, unsigned long, arg2, unsigned long, arg3,
+//zz                  unsigned long, arg4, unsigned long, arg5);
+//zz    // XXX: totally wrong... we need to look at the 'option' arg, and do
+//zz    // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
+//zz }
+//zz 
+//zz PRE(sys_sendfile, MayBlock)
+//zz {
+//zz    PRINT("sys_sendfile ( %d, %d, %p, %llu )", ARG1,ARG2,ARG3,(ULong)ARG4);
+//zz    PRE_REG_READ4(ssize_t, "sendfile",
+//zz                  int, out_fd, int, in_fd, vki_off_t *, offset,
+//zz                  vki_size_t, count);
+//zz    if (ARG3 != 0)
+//zz       PRE_MEM_WRITE( "sendfile(offset)", ARG3, sizeof(vki_off_t) );
+//zz }
+//zz 
+//zz POST(sys_sendfile)
+//zz {
+//zz    POST_MEM_WRITE( ARG3, sizeof( vki_off_t ) );
+//zz }
+//zz 
+//zz PRE(sys_sendfile64, MayBlock)
+//zz {
+//zz    PRINT("sendfile64 ( %d, %d, %p, %llu )",ARG1,ARG2,ARG3,(ULong)ARG4);
+//zz    PRE_REG_READ4(ssize_t, "sendfile64",
+//zz                  int, out_fd, int, in_fd, vki_loff_t *, offset,
+//zz                  vki_size_t, count);
+//zz    if (ARG3 != 0)
+//zz       PRE_MEM_WRITE( "sendfile64(offset)", ARG3, sizeof(vki_loff_t) );
+//zz }
+//zz 
+//zz POST(sys_sendfile64)
+//zz {
+//zz    if (ARG3 != 0 ) {
+//zz       POST_MEM_WRITE( ARG3, sizeof(vki_loff_t) );
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_futex, MayBlock)
+//zz {
+//zz    /* 
+//zz       arg    param                              used by ops
+//zz 
+//zz       ARG1 - u32 *futex				all
+//zz       ARG2 - int op
+//zz       ARG3 - int val				WAIT,WAKE,FD,REQUEUE,CMP_REQUEUE
+//zz       ARG4 - struct timespec *utime		WAIT:time*	REQUEUE,CMP_REQUEUE:val2
+//zz       ARG5 - u32 *uaddr2			REQUEUE,CMP_REQUEUE
+//zz       ARG6 - int val3				CMP_REQUEUE
+//zz     */
+//zz    PRINT("sys_futex ( %p, %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4,ARG5);
+//zz    PRE_REG_READ6(long, "futex", 
+//zz                  vki_u32 *, futex, int, op, int, val,
+//zz                  struct timespec *, utime, vki_u32 *, uaddr2, int, val3);
+//zz 
+//zz    PRE_MEM_READ( "futex(futex)", ARG1, sizeof(Int) );
+//zz 
+//zz    switch(ARG2) {
+//zz    case VKI_FUTEX_WAIT:
+//zz       if (ARG4 != 0)
+//zz 	 PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
+//zz       break;
+//zz 
+//zz    case VKI_FUTEX_REQUEUE:
+//zz    case VKI_FUTEX_CMP_REQUEUE:
+//zz       PRE_MEM_READ( "futex(futex2)", ARG5, sizeof(Int) );
+//zz       break;
+//zz 
+//zz    case VKI_FUTEX_WAKE:
+//zz    case VKI_FUTEX_FD:
+//zz       /* no additional pointers */
+//zz       break;
+//zz 
+//zz    default:
+//zz       SET_RESULT(-VKI_ENOSYS);   // some futex function we don't understand
+//zz       break;
+//zz    }
+//zz }
+//zz 
+//zz POST(sys_futex)
+//zz {
+//zz    POST_MEM_WRITE( ARG1, sizeof(int) );
+//zz    if (ARG2 == VKI_FUTEX_FD) {
+//zz       if (!VG_(fd_allowed)(RES, "futex", tid, True)) {
+//zz          VG_(close)(RES);
+//zz          SET_RESULT( -VKI_EMFILE );
+//zz       } else {
+//zz          if (VG_(clo_track_fds))
+//zz             VG_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+//zz       }
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_epoll_create, 0)
+//zz {
+//zz    PRINT("sys_epoll_create ( %d )", ARG1);
+//zz    PRE_REG_READ1(long, "epoll_create", int, size);
+//zz }
+//zz 
+//zz POST(sys_epoll_create)
+//zz {
+//zz    if (!VG_(fd_allowed)(RES, "epoll_create", tid, True)) {
+//zz       VG_(close)(RES);
+//zz       SET_RESULT( -VKI_EMFILE );
+//zz    } else {
+//zz       if (VG_(clo_track_fds))
+//zz          VG_(record_fd_open) (tid, RES, NULL);
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_epoll_ctl, 0)
+//zz {
+//zz    static const char* epoll_ctl_s[3] = {
+//zz       "EPOLL_CTL_ADD",
+//zz       "EPOLL_CTL_DEL",
+//zz       "EPOLL_CTL_MOD"
+//zz    };
+//zz    PRINT("sys_epoll_ctl ( %d, %s, %d, %p )", 
+//zz          ARG1, ( ARG2<3 ? epoll_ctl_s[ARG2] : "?" ), ARG3, ARG4);
+//zz    PRE_REG_READ4(long, "epoll_ctl",
+//zz                  int, epfd, int, op, int, fd, struct epoll_event *, event);
+//zz    PRE_MEM_READ( "epoll_ctl(event)", ARG4, sizeof(struct epoll_event) );
+//zz }
+//zz 
+//zz PRE(sys_epoll_wait, MayBlock)
+//zz {
+//zz    PRINT("sys_epoll_wait ( %d, %p, %d, %d )", ARG1, ARG2, ARG3, ARG4);
+//zz    PRE_REG_READ4(long, "epoll_wait",
+//zz                  int, epfd, struct epoll_event *, events,
+//zz                  int, maxevents, int, timeout);
+//zz    PRE_MEM_WRITE( "epoll_wait(events)", ARG2, sizeof(struct epoll_event)*ARG3);
+//zz }
+//zz 
+//zz POST(sys_epoll_wait)
+//zz {
+//zz    if (RES > 0)
+//zz       POST_MEM_WRITE( ARG2, sizeof(struct epoll_event)*RES ) ;
+//zz }
+//zz 
+//zz PRE(sys_gettid, 0)
+//zz {
+//zz    PRINT("sys_gettid ()");
+//zz    PRE_REG_READ0(long, "gettid");
+//zz }
+//zz 
+//zz PRE(sys_tkill, Special)
+//zz {
+//zz    /* int tkill(pid_t tid, int sig); */
+//zz    PRINT("sys_tkill ( %d, %d )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "tkill", int, tid, int, sig);
+//zz    if (!VG_(client_signal_OK)(ARG2)) {
+//zz       SET_RESULT( -VKI_EINVAL );
+//zz       return;
+//zz    }
+//zz 
+//zz    /* If we're sending SIGKILL, check to see if the target is one of
+//zz       our threads and handle it specially. */
+//zz    if (ARG2 == VKI_SIGKILL && VG_(do_sigkill)(ARG1, -1))
+//zz       SET_RESULT(0);
+//zz    else
+//zz       SET_RESULT(VG_(do_syscall2)(SYSNO, ARG1, ARG2));
+//zz 
+//zz    if (VG_(clo_trace_signals))
+//zz       VG_(message)(Vg_DebugMsg, "tkill: sent signal %d to pid %d",
+//zz 		   ARG2, ARG1);
+//zz    // Check to see if this kill gave us a pending signal
+//zz    XXX FIXME VG_(poll_signals)(tid);
+//zz }
+//zz 
+//zz PRE(sys_tgkill, Special)
+//zz {
+//zz    /* int tgkill(pid_t tgid, pid_t tid, int sig); */
+//zz    PRINT("sys_tgkill ( %d, %d, %d )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "tgkill", int, tgid, int, tid, int, sig);
+//zz    if (!VG_(client_signal_OK)(ARG3)) {
+//zz       SET_RESULT( -VKI_EINVAL );
+//zz       return;
+//zz    }
+//zz    
+//zz    /* If we're sending SIGKILL, check to see if the target is one of
+//zz       our threads and handle it specially. */
+//zz    if (ARG3 == VKI_SIGKILL && VG_(do_sigkill)(ARG2, ARG1))
+//zz       SET_RESULT(0);
+//zz    else
+//zz       SET_RESULT(VG_(do_syscall3)(SYSNO, ARG1, ARG2, ARG3));
+//zz 
+//zz    if (VG_(clo_trace_signals))
+//zz       VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
+//zz 		   ARG3, ARG1, ARG2);
+//zz    // Check to see if this kill gave us a pending signal
+//zz    XXX FIXME VG_(poll_signals)(tid);
+//zz }
+//zz 
+//zz POST(sys_tgkill)
+//zz {
+//zz    if (VG_(clo_trace_signals))
+//zz       VG_(message)(Vg_DebugMsg, "tgkill: sent signal %d to pid %d/%d",
+//zz                    ARG3, ARG1, ARG2);
+//zz    // Check to see if this kill gave us a pending signal
+//zz    XXX FIXME VG_(poll_signals)(tid);
+//zz }
+//zz 
+//zz PRE(sys_fadvise64, 0)
+//zz {
+//zz    PRINT("sys_fadvise64 ( %d, %lld, %lu, %d )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ4(long, "fadvise64",
+//zz                  int, fd, vki_loff_t, offset, vki_size_t, len, int, advice)
+//zz }
+//zz 
+//zz PRE(sys_fadvise64_64, 0)
+//zz {
+//zz    PRINT("sys_fadvise64_64 ( %d, %lld, %lld, %d )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ4(long, "fadvise64_64",
+//zz                  int, fd, vki_loff_t, offset, vki_loff_t, len, int, advice)
+//zz }
+//zz 
+//zz // Nb: this wrapper is "Special" because we have to pad/unpad memory around
+//zz // the syscall itself, and this allows us to control exactly the code that
+//zz // gets run while the padding is in place.
+//zz PRE(sys_io_setup, Special)
+//zz {
+//zz    SizeT size;
+//zz    Addr addr;
+//zz 
+//zz    PRINT("sys_io_setup ( %u, %p )", ARG1,ARG2);
+//zz    PRE_REG_READ2(long, "io_setup",
+//zz                  unsigned, nr_events, vki_aio_context_t *, ctxp);
+//zz    PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
+//zz    
+//zz    size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
+//zz                        ARG1*sizeof(struct vki_io_event));
+//zz    addr = VG_(find_map_space)(0, size, True);
+//zz    
+//zz    if (addr == 0) {
+//zz       SET_RESULT( -VKI_ENOMEM );
+//zz       return;
+//zz    }
+//zz 
+//zz    VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, SF_FIXED);
+//zz    
+//zz    VG_(pad_address_space)(0);
+//zz    SET_RESULT( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
+//zz    VG_(unpad_address_space)(0);
+//zz 
+//zz    if (RES == 0) {
+//zz       struct vki_aio_ring *r = *(struct vki_aio_ring **)ARG2;
+//zz         
+//zz       vg_assert(addr == (Addr)r);
+//zz       vg_assert(VG_(valid_client_addr)(addr, size, tid, "io_setup"));
+//zz                 
+//zz       VG_TRACK( new_mem_mmap, addr, size, True, True, False );
+//zz       POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
+//zz    }
+//zz    else {
+//zz       VG_(unmap_range)(addr, size);
+//zz    }
+//zz }
+//zz 
+//zz // Nb: This wrapper is "Special" because we need 'size' to do the unmap
+//zz // after the syscall.  We must get 'size' from the aio_ring structure,
+//zz // before the syscall, while the aio_ring structure still exists.  (And we
+//zz // know that we must look at the aio_ring structure because Tom inspected the
+//zz // kernel and glibc sources to see what they do, yuk.)
+//zz //
+//zz // XXX This segment can be implicitly unmapped when aio
+//zz // file-descriptors are closed...
+//zz PRE(sys_io_destroy, Special)
+//zz {     
+//zz    Segment *s = VG_(find_segment)(ARG1);
+//zz    struct vki_aio_ring *r;
+//zz    SizeT size;
+//zz       
+//zz    PRINT("sys_io_destroy ( %llu )", (ULong)ARG1);
+//zz    PRE_REG_READ1(long, "io_destroy", vki_aio_context_t, ctx);
+//zz 
+//zz    // If we are going to seg fault (due to a bogus ARG1) do it as late as
+//zz    // possible...
+//zz    r = *(struct vki_aio_ring **)ARG1;
+//zz    size = VG_PGROUNDUP(sizeof(struct vki_aio_ring) + 
+//zz                        r->nr*sizeof(struct vki_io_event));
+//zz 
+//zz    SET_RESULT( VG_(do_syscall1)(SYSNO, ARG1) );
+//zz 
+//zz    if (RES == 0 && s != NULL) { 
+//zz       VG_TRACK( die_mem_munmap, ARG1, size );
+//zz       VG_(unmap_range)(ARG1, size);
+//zz    }  
+//zz }  
+//zz 
+//zz PRE(sys_io_getevents, MayBlock)
+//zz {
+//zz    PRINT("sys_io_getevents ( %llu, %lld, %lld, %p, %p )",
+//zz          (ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
+//zz    PRE_REG_READ5(long, "io_getevents",
+//zz                  vki_aio_context_t, ctx_id, long, min_nr, long, nr,
+//zz                  struct io_event *, events,
+//zz                  struct timespec *, timeout);
+//zz    if (ARG3 > 0)
+//zz       PRE_MEM_WRITE( "io_getevents(events)",
+//zz                      ARG4, sizeof(struct vki_io_event)*ARG3 );
+//zz    if (ARG5 != 0)
+//zz       PRE_MEM_READ( "io_getevents(timeout)",
+//zz                     ARG5, sizeof(struct vki_timespec));
+//zz }
+//zz 
+//zz POST(sys_io_getevents)
+//zz {
+//zz    int i;
+//zz 
+//zz    if (RES > 0) {
+//zz       POST_MEM_WRITE( ARG4, sizeof(struct vki_io_event)*RES );
+//zz       for (i = 0; i < RES; i++) {
+//zz          const struct vki_io_event *vev = ((struct vki_io_event *)ARG4) + i;
+//zz          const struct vki_iocb *cb = (struct vki_iocb *)(Addr)vev->obj;
+//zz 
+//zz          switch (cb->aio_lio_opcode) {
+//zz          case VKI_IOCB_CMD_PREAD:
+//zz             if (vev->result > 0)
+//zz                POST_MEM_WRITE( cb->aio_buf, vev->result );
+//zz             break;
+//zz             
+//zz          case VKI_IOCB_CMD_PWRITE:
+//zz             break;
+//zz            
+//zz          default:
+//zz             VG_(message)(Vg_DebugMsg,"Warning: unhandled io_getevents opcode: %u\n",cb->aio_lio_opcode);
+//zz             break;
+//zz          }
+//zz       }
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_io_submit, 0)
+//zz {
+//zz    int i;
+//zz 
+//zz    PRINT("sys_io_submit( %llu, %lld, %p )", (ULong)ARG1,(Long)ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "io_submit",
+//zz                  vki_aio_context_t, ctx_id, long, nr,
+//zz                  struct iocb **, iocbpp);
+//zz    PRE_MEM_READ( "io_submit(iocbpp)", ARG3, ARG2*sizeof(struct vki_iocb *) );
+//zz    if (ARG3 != 0) {
+//zz       for (i = 0; i < ARG2; i++) {
+//zz          struct vki_iocb *cb = ((struct vki_iocb **)ARG3)[i];
+//zz          PRE_MEM_READ( "io_submit(iocb)", (Addr)cb, sizeof(struct vki_iocb) );
+//zz          switch (cb->aio_lio_opcode) {
+//zz          case VKI_IOCB_CMD_PREAD:
+//zz             PRE_MEM_WRITE( "io_submit(PREAD)", cb->aio_buf, cb->aio_nbytes );
+//zz             break;
+//zz 
+//zz          case VKI_IOCB_CMD_PWRITE:
+//zz             PRE_MEM_READ( "io_submit(PWRITE)", cb->aio_buf, cb->aio_nbytes );
+//zz             break;
+//zz            
+//zz          default:
+//zz             VG_(message)(Vg_DebugMsg,"Warning: unhandled io_submit opcode: %u\n",
+//zz                          cb->aio_lio_opcode);
+//zz             break;
+//zz          }
+//zz       }
+//zz    }
+//zz }
+//zz 
+//zz PRE(sys_io_cancel, 0)
+//zz {
+//zz    PRINT("sys_io_cancel( %llu, %p, %p )", (ULong)ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(long, "io_cancel",
+//zz                  vki_aio_context_t, ctx_id, struct iocb *, iocb,
+//zz                  struct io_event *, result);
+//zz    PRE_MEM_READ( "io_cancel(iocb)", ARG2, sizeof(struct vki_iocb) );
+//zz    PRE_MEM_WRITE( "io_cancel(result)", ARG3, sizeof(struct vki_io_event) );
+//zz }
+//zz 
+//zz POST(sys_io_cancel)
+//zz {
+//zz    POST_MEM_WRITE( ARG3, sizeof(struct vki_io_event) );
+//zz }
+//zz 
+//zz #undef PRE
+//zz #undef POST
 
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
diff --git a/coregrind/m_syscalls/syscalls-main.c b/coregrind/m_syscalls/syscalls-main.c
new file mode 100644
index 0000000..f2fbb08
--- /dev/null
+++ b/coregrind/m_syscalls/syscalls-main.c
@@ -0,0 +1,970 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Handle system calls.                         syscalls-main.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Valgrind, a dynamic binary instrumentation
+   framework.
+
+   Copyright (C) 2000-2005 Julian Seward 
+      jseward@acm.org
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "libvex_guest_offsets.h"
+#include "core.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_stacktrace.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_options.h"
+#include "pub_core_signals.h"
+#include "pub_core_syscalls.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-main.h"
+
+
+/* This is the top level of the system-call handler module.  All
+   system calls are channelled through here, doing two things:
+
+   * notify the tool of the events (mem/reg reads, writes) happening
+
+   * perform the syscall, usually by passing it along to the kernel
+     unmodified.
+
+   A magical piece of assembly code, do_syscall_for_client_WRK, in
+   syscall-$PLATFORM.S does the tricky bit of passing a syscall to the
+   kernel, whilst having the simulator retain control.
+*/
+
+/* The main function is VG_(client_syscall).  The simulation calls it
+   whenever a client thread wants to do a syscall.  The following is a
+   sketch of what it does.
+
+   * First, it rounds up the syscall number and args (which is a
+     platform dependent activity) and puts them in a struct ("args")
+     and also a copy in "orig_args".
+
+     The pre/post wrappers refer to these structs and so no longer
+     need magic macros to access any specific registers.  This struct
+     is stored in thread-specific storage.
+
+
+   * The pre-wrapper is called, passing it a pointer to struct
+     "args".
+
+
+   * The pre-wrapper examines the args and pokes the tool
+     appropriately.  It may modify the args; this is why "orig_args"
+     is also stored.
+
+     The pre-wrapper may choose to 'do' the syscall itself, and
+     concludes one of three outcomes:
+
+       Success(N)    -- syscall is already complete, with success;
+                        result is N
+
+       Fail(N)       -- syscall is already complete, with failure;
+                        error code is N
+
+       HandToKernel  -- (the usual case): this needs to be given to
+                        the kernel to be done, using the values in
+                        the possibly-modified "args" struct.
+
+     In addition, the pre-wrapper may set some flags:
+
+       MayBlock   -- only applicable when outcome==HandToKernel
+
+       PostOnFail -- only applicable when outcome==HandToKernel or Fail
+
+
+   * If the pre-outcome is HandToKernel, the syscall is duly handed
+     off to the kernel (perhaps involving some thread switchery, but
+     that's not important).  This reduces the possible set of outcomes
+     to either Success(N) or Fail(N).
+
+
+   * The outcome (Success(N) or Fail(N)) is written back to the guest
+     register(s).  This is platform specific:
+
+     x86:    Success(N) ==>  eax = N
+             Fail(N)    ==>  eax = -N
+
+     ditto amd64
+
+     ppc32:  Success(N) ==>  r3 = N, CR0.SO = 0
+             Fail(N) ==>     r3 = N, CR0.SO = 1
+
+   * The post wrapper is called if:
+
+     - it exists, and
+     - outcome==Success or (outcome==Fail and PostOnFail is set)
+
+     The post wrapper is passed the adulterated syscall args (struct
+     "args"), and the syscall outcome (viz, Success(N) or Fail(N)).
+
+   There are several other complications, primarily to do with
+   syscalls getting interrupted, explained in comments in the code.
+*/
+
+/* CAVEATS for writing wrappers.  It is important to follow these!
+
+   The macros defined in priv_types_n_macros.h are designed to help
+   decouple the wrapper logic from the actual representation of
+   syscall args/results, since these wrappers are designed to work on
+   multiple platforms.
+
+   Sometimes a PRE wrapper will complete the syscall itself, without
+   handing it to the kernel.  It will use one of SET_STATUS_Success,
+   SET_STATUS_Failure or SET_STATUS_from_SysRes to set the return
+   value.  It is critical to appreciate that use of the macro does not
+   immediately cause the underlying guest state to be updated -- that
+   is done by the driver logic in this file, when the wrapper returns.
+
+   As a result, PRE wrappers of the following form will malfunction:
+
+   PRE(fooble) 
+   {
+      ... do stuff ...
+      SET_STATUS_Somehow(...)
+
+      // do something that assumes guest state is up to date
+   }
+
+   In particular, direct or indirect calls to VG_(poll_signals) after
+   setting STATUS can cause the guest state to be read (in order to
+   build signal frames).  Do not do this.  If you want a signal poll
+   after the syscall goes through, do "*flags |= SfPollAfter" and the
+   driver logic will do it for you.
+*/
+
+
+/* ---------------------------------------------------------------------
+   Do potentially blocking syscall for the client, and mess with 
+   signal masks at the same time. 
+   ------------------------------------------------------------------ */
+
+/* Perform a syscall on behalf of a client thread, using a specific
+   signal mask.  On completion, the signal mask is set to restore_mask
+   (which presumably blocks almost everything).  If a signal happens
+   during the syscall, the handler should call
+   VG_(fixup_guest_state_after_syscall_interrupted) to adjust the
+   thread's context to do the right thing.
+
+   The _WRK function is handwritten assembly.  It has some very magic
+   properties.  See comments at the top of
+   VG_(fixup_guest_state_after_syscall_interrupted) below for details.
+*/
+extern
+void VGA_(do_syscall_for_client_WRK)( Int syscallno, 
+                                      void* guest_state,
+                                      const vki_sigset_t *syscall_mask,
+                                      const vki_sigset_t *restore_mask,
+                                      Int nsigwords );
+
+static
+void do_syscall_for_client ( Int syscallno,
+                             ThreadState* tst,
+                             const vki_sigset_t* syscall_mask )
+{
+   vki_sigset_t saved;
+   VGA_(do_syscall_for_client_WRK)(
+      syscallno, &tst->arch.vex, 
+      syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord)
+   );
+}
+
+
+
+/* ---------------------------------------------------------------------
+   Impedance matchers and misc helpers
+   ------------------------------------------------------------------ */
+
+static
+Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
+{
+   return a1->sysno == a2->sysno
+          && a1->arg1 == a2->arg1
+          && a1->arg2 == a2->arg2
+          && a1->arg3 == a2->arg3
+          && a1->arg4 == a2->arg4
+          && a1->arg5 == a2->arg5
+          && a1->arg6 == a2->arg6;
+}
+
+static
+Bool eq_SyscallStatus ( SyscallStatus* s1, SyscallStatus* s2 )
+{
+   return s1->what == s2->what 
+          && s1->val == s2->val;
+}
+
+
+/* Convert between SysRet and SyscallStatus, to the extent possible. */
+
+/* This is unused. */
+/*
+static
+SysRes convert_SyscallStatus_to_SysRes ( SyscallStatus status )
+{
+   SysRes res;
+   vg_assert(status.what == SsSuccess || status.what == SsFailure);
+   res.isError = status.what == SsFailure;
+   res.val     = status.val;
+   return res;
+}
+*/
+
+static
+SyscallStatus convert_SysRes_to_SyscallStatus ( SysRes res )
+{
+   SyscallStatus status;
+   status.what = res.isError ? SsFailure : SsSuccess;
+   status.val  = res.val;
+   return status;
+}
+
+
+/* Impedance matchers.  These convert syscall arg or result data from
+   the platform-specific in-guest-state format to the canonical
+   formats, and back. */
+
+static 
+void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs*       canonical,
+                                    /*IN*/ VexGuestArchState* gst_vanilla )
+{
+#  if defined(VGP_x86_linux)
+   VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+   canonical->sysno = gst->guest_EAX;
+   canonical->arg1  = gst->guest_EBX;
+   canonical->arg2  = gst->guest_ECX;
+   canonical->arg3  = gst->guest_EDX;
+   canonical->arg4  = gst->guest_ESI;
+   canonical->arg5  = gst->guest_EDI;
+   canonical->arg6  = gst->guest_EBP;
+#  else
+#    error "getSyscallArgsFromGuestState: unknown arch"
+#  endif
+}
+
+static 
+void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs*       canonical,
+                                    /*OUT*/VexGuestArchState* gst_vanilla )
+{
+#  if defined(VGP_x86_linux)
+   VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+   gst->guest_EAX = canonical->sysno;
+   gst->guest_EBX = canonical->arg1;
+   gst->guest_ECX = canonical->arg2;
+   gst->guest_EDX = canonical->arg3;
+   gst->guest_ESI = canonical->arg4;
+   gst->guest_EDI = canonical->arg5;
+   gst->guest_EBP = canonical->arg6;
+#  else
+#    error "putSyscallArgsIntoGuestState: unknown arch"
+#  endif
+}
+
+static
+void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus*     canonical,
+                                      /*IN*/ VexGuestArchState* gst_vanilla )
+{
+#  if defined(VGP_x86_linux)
+   VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+   Int               i   = (Int)gst->guest_EAX;
+   canonical->what = i >= -4095 && i <= -1  ? SsFailure  : SsSuccess;
+   canonical->val  = (UWord)(canonical->what==SsFailure ? -i : i);
+#  else
+#    error "getSyscallStatusFromGuestState: unknown arch"
+#  endif
+}
+
+static 
+void putSyscallStatusIntoGuestState ( /*IN*/ SyscallStatus*     canonical,
+                                      /*OUT*/VexGuestArchState* gst_vanilla )
+{
+   vg_assert(canonical->what == SsSuccess 
+             || canonical->what == SsFailure);
+#  if defined(VGP_x86_linux)
+   VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
+   if (canonical->what == SsFailure) {
+      /* This isn't exactly right, in that really a Failure with res
+         not in the range 1 .. 4095 is unrepresentable in the
+         Linux-x86 scheme.  Oh well. */
+      gst->guest_EAX = - (Int)canonical->val;
+   } else {
+      gst->guest_EAX = canonical->val;
+   }
+#  else
+#    error "putSyscallStatusIntoGuestState: unknown arch"
+#  endif
+}
+
+
+/* Tell me the offsets in the guest state of the syscall params, so
+   that the scalar argument checkers don't have to have this info
+   hardwired. */
+
+static
+void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
+{
+#  if defined(VGP_x86_linux)
+   layout->o_sysno  = OFFSET_x86_EAX;
+   layout->o_arg1   = OFFSET_x86_EBX;
+   layout->o_arg2   = OFFSET_x86_ECX;
+   layout->o_arg3   = OFFSET_x86_EDX;
+   layout->o_arg4   = OFFSET_x86_ESI;
+   layout->o_arg5   = OFFSET_x86_EDI;
+   layout->o_arg6   = OFFSET_x86_EBP;
+   layout->o_retval = OFFSET_x86_EAX;
+#  else
+#    error "getSyscallLayout: unknown arch"
+#  endif
+}
+
+
+/* ---------------------------------------------------------------------
+   The main driver logic
+   ------------------------------------------------------------------ */
+
+/* Finding the handlers for a given syscall, or faking up one
+   when no handler is found. */
+
+static 
+void bad_before ( ThreadId              tid,
+                  SyscallArgLayout*     layout,
+                  /*MOD*/SyscallArgs*   args,
+                  /*OUT*/SyscallStatus* status,
+                  /*OUT*/UWord*         flags )
+{
+   VG_(message)
+      (Vg_DebugMsg,"WARNING: unhandled syscall: %llu", (ULong)args->sysno);
+   if (VG_(clo_verbosity) > 1) {
+      VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
+   }
+   VG_(message)
+      (Vg_DebugMsg,"You may be able to write your own handler.");
+   VG_(message)
+      (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
+
+   SET_STATUS_Failure(VKI_ENOSYS);
+}
+
+static SyscallTableEntry bad_sys =
+   { bad_before, NULL };
+
+static const SyscallTableEntry* get_syscall_entry ( UInt syscallno )
+{
+   const SyscallTableEntry* sys = &bad_sys;
+
+   if (syscallno < VGP_(syscall_table_size) &&
+       VGP_(syscall_table)[syscallno].before != NULL)
+      sys = &VGP_(syscall_table)[syscallno];
+
+   return sys;
+}
+
+
+/* Add and remove signals from mask so that we end up telling the
+   kernel the state we actually want rather than what the client
+   wants. */
+static void sanitize_client_sigmask(ThreadId tid, vki_sigset_t *mask)
+{
+   VG_(sigdelset)(mask, VKI_SIGKILL);
+   VG_(sigdelset)(mask, VKI_SIGSTOP);
+   VG_(sigdelset)(mask, VKI_SIGVGKILL); /* never block */
+}
+
+typedef
+   struct {
+      SyscallArgs   orig_args;
+      SyscallArgs   args;
+      SyscallStatus status;
+      UWord         flags;
+   }
+   SyscallInfo;
+
+SyscallInfo syscallInfo[VG_N_THREADS];
+
+
+/* The scheduler needs to be able to zero out these records after a
+   fork, hence this is exported from m_syscalls. */
+void VG_(clear_syscallInfo) ( Int tid )
+{
+   vg_assert(tid >= 0 && tid < VG_N_THREADS);
+   VG_(memset)( & syscallInfo[tid], 0, sizeof( syscallInfo[tid] ));
+   syscallInfo[tid].status.what = SsIdle;
+}
+
+static void ensure_initialised ( void )
+{
+   Int i;
+   static Bool init_done = False;
+   if (init_done) 
+      return;
+   init_done = True;
+   for (i = 0; i < VG_N_THREADS; i++) {
+      VG_(clear_syscallInfo)( i );
+   }
+}
+
+/* --- This is the main function of this file. --- */
+
+void VG_(client_syscall) ( ThreadId tid )
+{
+   UWord                    sysno;
+   ThreadState*             tst;
+   const SyscallTableEntry* ent;
+   SyscallArgLayout         layout;
+   SyscallInfo*             sci;
+
+   ensure_initialised();
+
+   vg_assert(VG_(is_valid_tid)(tid));
+   vg_assert(tid >= 1 && tid < VG_N_THREADS);
+   vg_assert(VG_(is_running_thread)(tid));
+
+   tst = VG_(get_ThreadState)(tid);
+
+   /* First off, get the syscall args and number.  This is a
+      platform-dependent action. */
+
+   sci = & syscallInfo[tid];
+   vg_assert(sci->status.what == SsIdle);
+
+   getSyscallArgsFromGuestState( &sci->orig_args, &tst->arch.vex );
+
+   /* Copy .orig_args to .args.  The pre-handler may modify .args, but
+      we want to keep the originals too, just in case. */
+   sci->args = sci->orig_args;
+
+   /* Save the syscall number in the thread state in case the syscall 
+      is interrupted by a signal. */
+   sysno = sci->orig_args.sysno;
+
+   /* The default what-to-do-next thing is hand the syscall to the
+      kernel, so we pre-set that here. */
+   sci->status.what = SsHandToKernel;
+   sci->status.val  = 0;
+   sci->flags       = 0;
+
+   /* Fetch the syscall's handlers.  If no handlers exist for this
+      syscall, we are given dummy handlers which force an immediate
+      return with ENOSYS. */
+   ent = get_syscall_entry(sysno);
+
+   /* Fetch the layout information, which tells us where in the guest
+      state the syscall args reside.  This is a platform-dependent
+      action.  This info is needed so that the scalar syscall argument
+      checks (PRE_REG_READ calls) know which bits of the guest state
+      they need to inspect. */
+   getSyscallArgLayout( &layout );
+
+   /* Make sure the tmp signal mask matches the real signal mask;
+      sigsuspend may change this. */
+   vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
+
+   /* Right, we're finally ready to Party.  Call the pre-handler and
+      see what we get back.  At this point: 
+
+        sci->status.what  is Unset (we don't know yet).
+        sci->orig_args    contains the original args.
+        sci->args         is the same as sci->orig_args.
+        sci->flags        is zero.
+   */
+
+   PRINT("SYSCALL[%d,%d](%3lld) ", VG_(getpid)(), tid, (ULong)sysno);
+
+   /* Do any pre-syscall actions */
+   if (VG_(needs).syscall_wrapper) {
+      VG_TDICT_CALL(tool_pre_syscall, tid, sysno);
+   }
+
+   vg_assert(ent);
+   vg_assert(ent->before);
+   (ent->before)( tid,
+                  &layout, 
+                  &sci->args, &sci->status, &sci->flags );
+   
+   /* The pre-handler may have modified:
+         sci->args
+         sci->status
+         sci->flags
+      All else remains unchanged. 
+      Although the args may be modified, pre handlers are not allowed
+      to change the syscall number.
+   */
+   /* Now we proceed according to what the pre-handler decided. */
+   vg_assert(sci->status.what == SsHandToKernel
+             || sci->status.what == SsSuccess
+             || sci->status.what == SsFailure);
+   vg_assert(sci->args.sysno == sci->orig_args.sysno);
+
+   if (sci->status.what == SsSuccess) {
+      /* The pre-handler completed the syscall itself, declaring
+         success. */
+      PRINT(" --> [pre-success] Success(0x%llx)\n", (Long)sci->status.val );
+                                       
+      /* In this case thes allowable flag are to ask for a signal-poll
+         and/or a yield after the call.  Changing the args isn't
+         allowed. */
+      vg_assert(0 == (sci->flags & ~(SfPollAfter | SfYieldAfter)));
+      vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
+   }
+
+   else
+   if (sci->status.what == SsFailure) {
+      /* The pre-handler decided to fail syscall itself. */
+      PRINT(" --> [pre-fail] Failure(0x%llx)\n", (Long)sci->status.val );
+      /* In this case, the pre-handler is also allowed to ask for the
+         post-handler to be run anyway.  Changing the args is not
+         allowed. */
+      vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter)));
+      vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
+   }
+
+   else
+   if (sci->status.what != SsHandToKernel) {
+      /* huh?! */
+      vg_assert(0);
+   }
+
+   else /* (sci->status.what == HandToKernel) */ {
+      /* Ok, this is the usual case -- and the complicated one.  There
+         are two subcases: sync and async.  async is the general case
+         and is to be used when there is any possibility that the
+         syscall might block [a fact that the pre-handler must tell us
+         via the sci->flags field.]  Because the tidying-away /
+         context-switch overhead of the async case could be large, if
+         we are sure that the syscall will not block, we fast-track it
+         by doing it directly in this thread, which is a lot
+         simpler. */
+
+      /* Check that the given flags are allowable: MayBlock and
+         PostOnFail are ok. */
+      vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail)));
+
+      if (sci->flags & SfMayBlock) {
+
+         /* Syscall may block, so run it asynchronously */
+         vki_sigset_t mask;
+
+//         vg_assert(!(sci->flags & PadAddr));
+         PRINT(" --> [async] ... \n");
+
+         mask = tst->sig_mask;
+         sanitize_client_sigmask(tid, &mask);
+
+         /* Gack.  More impedance matching.  Copy the possibly
+            modified syscall args back into the guest state. */
+         vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
+         putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex );
+
+         /* Drop the lock */
+         VG_(set_sleeping)(tid, VgTs_WaitSys);
+
+         /* Do the call, which operates directly on the guest state,
+            not on our abstracted copies of the args/result. */
+         do_syscall_for_client(sysno, tst, &mask);
+
+         /* do_syscall_for_client may not return if the syscall was
+            interrupted by a signal.  In that case, flow of control is
+            first to m_signals.async_sighandler, which calls
+            VG_(fixup_guest_state_after_syscall_interrupted), which
+            fixes up the guest state, and possibly calls
+            VG_(post_syscall).  Once that's done, control drops back
+            to the scheduler.  */
+
+         /* Reacquire the lock */
+         VG_(set_running)(tid);
+
+         /* Even more impedance matching.  Extract the syscall status
+            from the guest state. */
+         getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex );
+
+         PRINT("SYSCALL[%d,%d](%3d) ... [async] --> %s(0x%llx)\n",
+               VG_(getpid)(), tid, sysno, 
+               sci->status.what==SsSuccess ? "Success" : "Failure",
+               (Long)sci->status.val );
+
+      } else {
+
+         /* run the syscall directly */
+         /* The pre-handler may have modified the syscall args, but
+            since we're passing values in ->args directly to the
+            kernel, there's no point in flushing them back to the
+            guest state.  Indeed doing so could be construed as
+            incorrect. */
+
+//         if (sci->flags & PadAddr)
+//            VG_(pad_address_space)(VG_(client_end));
+
+         SysRes sres 
+            = VG_(do_syscall6)(sysno, sci->args.arg1, sci->args.arg2, 
+                                      sci->args.arg3, sci->args.arg4, 
+                                      sci->args.arg5, sci->args.arg6 );
+         sci->status = convert_SysRes_to_SyscallStatus(sres);
+
+         PRINT("[sync] --> %s(0x%llx)\n",
+               sci->status.what==SsSuccess ? "Success" : "Failure",
+               (Long)sci->status.val );
+      }
+   }
+
+   vg_assert(sci->status.what == SsFailure 
+             || sci->status.what == SsSuccess);
+
+   vg_assert(VG_(is_running_thread)(tid));
+
+   /* Dump the syscall result back in the guest state.  This is
+      a platform-specific action. */
+   putSyscallStatusIntoGuestState( &sci->status, &tst->arch.vex );
+
+   /* Situation now:
+      - the guest state is now correctly modified following the syscall
+      - modified args, original args and syscall status are still
+        available in the syscallInfo[] entry for this syscall.
+
+      Now go on to do the post-syscall actions (read on down ..)
+   */
+   VG_(post_syscall)(tid);
+}
+
+
+/* Perform post syscall actions.  The expected state on entry is
+   precisely as at the end of VG_(client_syscall), that is:
+
+   - guest state up to date following the syscall
+   - modified args, original args and syscall status are still
+     available in the syscallInfo[] entry for this syscall.
+   - syscall status matches what's in the guest state.
+
+   There are two ways to get here: the normal way -- being called by
+   VG_(client_syscall), and the unusual way, from
+   VG_(fixup_guest_state_after_syscall_interrupted).
+*/
+void VG_(post_syscall) (ThreadId tid)
+{
+   SyscallArgLayout         layout;
+   SyscallInfo*             sci;
+   const SyscallTableEntry* ent;
+   SyscallStatus            test_status;
+   ThreadState*             tst;
+   UWord sysno;
+
+   /* Preliminaries */
+   vg_assert(VG_(is_valid_tid)(tid));
+   vg_assert(tid >= 1 && tid < VG_N_THREADS);
+   vg_assert(VG_(is_running_thread)(tid));
+
+   tst = VG_(get_ThreadState)(tid);
+   sci = & syscallInfo[tid];
+
+   /* m_signals.sigvgkill_handler might call here even when not in
+      a syscall. */
+   if (sci->status.what == SsIdle || sci->status.what == SsHandToKernel) {
+      sci->status.what = SsIdle;
+      return;
+   }
+
+   /* Validate current syscallInfo entry.  In particular we require
+      that the current .status matches what's actually in the guest
+      state. */
+   vg_assert(sci->status.what == SsFailure 
+             || sci->status.what == SsSuccess);
+
+   getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
+   vg_assert(eq_SyscallStatus( &sci->status, &test_status ));
+   /* Ok, looks sane */
+
+   /* Get the system call number.  Because the pre-handler isn't
+      allowed to mess with it, it should be the same for both the
+      original and potentially-modified args. */
+   vg_assert(sci->args.sysno == sci->orig_args.sysno);
+   sysno = sci->args.sysno;
+   ent = get_syscall_entry(sysno);
+
+   /* We need the arg layout .. sigh */
+   getSyscallArgLayout( &layout );
+
+   /* Tell the tool that the assignment has occurred, so it can update
+      shadow regs as necessary. */
+   VG_TRACK( post_reg_write, Vg_CoreSysCall, tid, layout.o_retval, 
+                                                  sizeof(UWord) );
+
+   /* Consider, either success or failure.  Now run the post handler if:
+      - it exists, and
+      - status==Success or (status==Fail and PostOnFail is set)
+   */
+   if (ent->after
+       && (sci->status.what == SsSuccess
+           || (sci->status.what == SsFailure
+               && (sci->flags & SfPostOnFail) ))) {
+
+      (ent->after)( tid, &sci->args, &sci->status );
+   }
+
+   /* Because the post handler might have changed the status (eg, the
+      post-handler for sys_open can change the result from success to
+      failure if the kernel supplied a fd that it doesn't like), once
+      again dump the syscall result back in the guest state.*/
+   putSyscallStatusIntoGuestState( &sci->status, &tst->arch.vex );
+
+   /* Do any post-syscall actions required by the tool. */
+   if (VG_(needs).syscall_wrapper) {
+      SysRes res;
+      res.val     = sci->status.val;
+      res.isError = sci->status.what == SsFailure;
+      VG_TDICT_CALL(tool_post_syscall, tid, sysno, res);
+   }
+
+//zz    if (flags & PadAddr) {
+//zz       vg_assert(!mayBlock);
+//zz       VG_(unpad_address_space)(VG_(client_end));
+//zz       //VG_(sanity_check_memory)();
+//zz    }
+//zz 
+
+   /* The syscall is done. */
+   sci->status.what = SsIdle;
+
+   /* The pre/post wrappers may have concluded that pending signals
+      might have been created, and will have set SfPollAfter to
+      request a poll for them once the syscall is done. */
+   if (sci->flags & SfPollAfter)
+      VG_(poll_signals)(tid);
+
+   /* Similarly, the wrappers might have asked for a yield
+      afterwards. */
+   if (sci->flags & SfYieldAfter)
+      VG_(vg_yield)();
+}
+
+
+/* ---------------------------------------------------------------------
+   Dealing with syscalls which get interrupted by a signal:
+   VG_(fixup_guest_state_after_syscall_interrupted)
+   ------------------------------------------------------------------ */
+
+/* Syscalls done on behalf of the client are finally handed off to the
+   kernel in VG_(client_syscall) above, either by calling
+   do_syscall_for_client (the async case), or by calling
+   VG_(do_syscall6) (the sync case).
+
+   If the syscall is not interrupted by a signal (it may block and
+   later unblock, but that's irrelevant here) then those functions
+   eventually return and so control is passed to VG_(post_syscall).
+   NB: not sure if the sync case can actually get interrupted, as it
+   operates with all signals masked.
+
+   However, the syscall may get interrupted by an async-signal.  In
+   that case do_syscall_for_client/VG_(do_syscall6) do not
+   return.  Instead we wind up in m_signals.async_sighandler.  We need
+   to fix up the guest state to make it look like the syscall was
+   interrupted for guest.  So async_sighandler calls here, and this
+   does the fixup.  Note that from here we wind up calling
+   VG_(post_syscall) too.
+*/
+
+
+/* These are addresses within VGA_(_do_syscall_for_client).  See syscall.S for
+   details. */
+extern const Addr VGA_(blksys_setup);
+extern const Addr VGA_(blksys_restart);
+extern const Addr VGA_(blksys_complete);
+extern const Addr VGA_(blksys_committed);
+extern const Addr VGA_(blksys_finished);
+
+
+/* Back up guest state to restart a system call. */
+
+void VG_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
+{
+#  if defined(VGP_x86_linux)
+   arch->vex.guest_EIP -= 2;             // sizeof(int $0x80)
+
+   /* Make sure our caller is actually sane, and we're really backing
+      back over a syscall.
+
+      int $0x80 == CD 80 
+   */
+   {
+      UChar *p = (UChar *)arch->vex.guest_EIP;
+      
+      if (p[0] != 0xcd || p[1] != 0x80)
+         VG_(message)(Vg_DebugMsg,
+                      "?! restarting over syscall at %p %02x %02x\n",
+                      arch->vex.guest_EIP, p[0], p[1]); 
+
+      vg_assert(p[0] == 0xcd && p[1] == 0x80);
+   }
+#  else
+
+#    error "VG_(fixup_guest_state_to_restart_syscall): unknown plat"
+#  endif
+}
+
+/* 
+   Fix up the guest state when a syscall is interrupted by a signal
+   and so has been forced to return 'sysret'.
+
+   To do this, we determine the precise state of the syscall by
+   looking at the (real) IP at the time the signal happened.  The
+   syscall sequence looks like:
+
+     1. unblock signals
+     2. perform syscall
+     3. save result to guest state (EAX, RAX, R3+CR0.SO)
+     4. re-block signals
+
+   If a signal
+   happens at      Then     Why?
+   [1-2)           restart  nothing has happened (restart syscall)
+   [2]             restart  syscall hasn't started, or kernel wants to restart
+   [2-3)           save     syscall complete, but results not saved
+   [3-4)           syscall complete, results saved
+
+   Sometimes we never want to restart an interrupted syscall (because
+   sigaction says not to), so we only restart if "restart" is True.
+
+   This will also call VG_(post_syscall) if the syscall has actually
+   completed (either because it was interrupted, or because it
+   actually finished).  It will not call VG_(post_syscall) if the
+   syscall is set up for restart, which means that the pre-wrapper may
+   get called multiple times.
+*/
+
+void 
+VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid, 
+                                                  Addr     ip, 
+                                                  UWord    sysnum, 
+                                                  SysRes   sysret,
+                                                  Bool     restart)
+{
+   /* Note that the sysnum arg seems to contain not-dependable-on info
+      (I think it depends on the state the real syscall was in at
+      interrupt) and so is ignored, apart from in the following
+      printf. */
+
+   static const Bool debug = False;
+
+   ThreadState*     tst;
+   SyscallStatus    canonical;
+   ThreadArchState* th_regs;
+   SyscallInfo*     sci;
+
+   if (debug)
+      VG_(printf)( "interrupted_syscall %d: tid=%d, IP=0x%llx, "
+                   "restart=%s, sysret.isError=%s, sysret.val=%lld\n", 
+                   (Int)sysnum,
+                   (Int)tid,
+                   (ULong)ip, 
+                   restart ? "True" : "False", 
+                   sysret.isError ? "True" : "False",
+                   (Long)(Word)sysret.val );
+
+   vg_assert(VG_(is_valid_tid)(tid));
+   vg_assert(tid >= 1 && tid < VG_N_THREADS);
+   vg_assert(VG_(is_running_thread)(tid));
+
+   tst     = VG_(get_ThreadState)(tid);
+   th_regs = &tst->arch;
+   sci     = & syscallInfo[tid];
+
+   /* Figure out what the state of the syscall was by examining the
+      (real) IP at the time of the signal, and act accordingly. */
+
+   if (ip < VGA_(blksys_setup) || ip >= VGA_(blksys_finished)) {
+      VG_(printf)("  not in syscall (%p - %p)\n", 
+                  VGA_(blksys_setup), VGA_(blksys_finished));
+      /* Looks like we weren't in a syscall at all.  Hmm. */
+      vg_assert(sci->status.what != SsIdle);
+      return;
+   }
+
+   /* We should not be here unless this thread had first started up
+      the machinery for a syscall by calling VG_(client_syscall).
+      Hence: */
+   vg_assert(sci->status.what != SsIdle);
+
+   if (ip >= VGA_(blksys_setup) && ip < VGA_(blksys_restart)) {
+      /* syscall hasn't even started; go around again */
+      if (debug)
+         VG_(printf)("  not started: restart\n");
+      vg_assert(sci->status.what == SsHandToKernel);
+      VG_(fixup_guest_state_to_restart_syscall)(th_regs);
+   } 
+
+   else 
+   if (ip == VGA_(blksys_restart)) {
+      /* We're either about to run the syscall, or it was interrupted
+         and the kernel restarted it.  Restart if asked, otherwise
+         EINTR it. */
+      if (restart)
+         VG_(fixup_guest_state_to_restart_syscall)(th_regs);
+      else {
+         canonical = convert_SysRes_to_SyscallStatus( 
+                        VG_(mk_SysRes_Error)( VKI_EINTR ) 
+                     );
+         putSyscallStatusIntoGuestState( &canonical, &th_regs->vex );
+         sci->status = canonical;
+         VG_(post_syscall)(tid);
+      }
+   }
+
+   else 
+   if (ip >= VGA_(blksys_complete) && ip < VGA_(blksys_committed)) {
+      /* Syscall complete, but result hasn't been written back yet.
+         Write the SysRes we were supplied with back to the guest
+         state. */
+      if (debug)
+         VG_(printf)("  completed\n", sysret);
+      canonical = convert_SysRes_to_SyscallStatus( sysret );
+      putSyscallStatusIntoGuestState( &canonical, &th_regs->vex );
+      sci->status = canonical;
+      VG_(post_syscall)(tid);
+   } 
+
+   else 
+   if (ip >= VGA_(blksys_committed) && ip < VGA_(blksys_finished)) {
+      /* Result committed, but the signal mask has not been restored;
+         we expect our caller (the signal handler) will have fixed
+         this up. */
+      if (debug)
+         VG_(printf)("  all done\n");
+      VG_(post_syscall)(tid);
+   } 
+
+   else
+      VG_(core_panic)("?? strange syscall interrupt state?");
+
+   /* In all cases, the syscall is now finished (even if we called
+      VG_(fixup_guest_state_to_restart_syscall), since that just
+      re-positions the guest's IP for another go at it).  So we need
+      to record that fact. */
+   sci->status.what = SsIdle;
+}
+
+
+/*--------------------------------------------------------------------*/
+/*--- end                                          syscalls-main.c ---*/
+/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_syscalls/syscalls-x86-linux.c b/coregrind/m_syscalls/syscalls-x86-linux.c
index 691be02..74f9bb1 100644
--- a/coregrind/m_syscalls/syscalls-x86-linux.c
+++ b/coregrind/m_syscalls/syscalls-x86-linux.c
@@ -37,12 +37,21 @@
 #include "ume.h"                /* for jmp_with_stack */
 #include "pub_core_debuglog.h"
 #include "pub_core_aspacemgr.h"
+#include "pub_core_options.h"
+#include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcprint.h"
 #include "pub_core_sigframe.h"
 #include "pub_core_syscalls.h"
 #include "pub_core_tooliface.h"
-#include "priv_syscalls.h"
+#include "pub_core_signals.h"
+
+#include "priv_types_n_macros.h"
+#include "priv_syscalls-generic.h"   /* for decls of generic wrappers */
+#include "priv_syscalls-linux.h"     /* for decls of linux-ish wrappers */
+#include "priv_syscalls-main.h"
+
+#include "vki_unistd.h"              /* for the __NR_* constants */
 
 
 /* ---------------------------------------------------------------------
@@ -50,137 +59,6 @@
    Note.  Why is this stuff here?
    ------------------------------------------------------------------ */
 
-
-/* These are addresses within VGA_(client_syscall).  See syscall.S for details. */
-extern const Addr VGA_(blksys_setup);
-extern const Addr VGA_(blksys_restart);
-extern const Addr VGA_(blksys_complete);
-extern const Addr VGA_(blksys_committed);
-extern const Addr VGA_(blksys_finished);
-
-// Back up to restart a system call.
-static void restart_syscall(ThreadArchState *arch)
-{
-   arch->vex.guest_EIP -= 2;             // sizeof(int $0x80)
-
-   /* Make sure our caller is actually sane, and we're really backing
-      back over a syscall.
-
-      int $0x80 == CD 80 
-   */
-   {
-      UChar *p = (UChar *)arch->vex.guest_EIP;
-      
-      if (p[0] != 0xcd || p[1] != 0x80)
-         VG_(message)(Vg_DebugMsg,
-                      "?! restarting over syscall at %p %02x %02x\n",
-                      arch->vex.guest_EIP, p[0], p[1]); 
-
-      vg_assert(p[0] == 0xcd && p[1] == 0x80);
-   }
-}
-
-/* 
-   Fix up the VCPU state when a syscall is interrupted by a signal.
-
-   To do this, we determine the precise state of the syscall by
-   looking at the (real) eip at the time the signal happened.  The
-   syscall sequence looks like:
-
-     1. unblock signals
-     2. perform syscall
-     3. save result to EAX
-     4. re-block signals
-
-   If a signal
-   happens at      Then     Why?
-   [1-2)           restart  nothing has happened (restart syscall)
-   [2]             restart  syscall hasn't started, or kernel wants to restart
-   [2-3)           save     syscall complete, but results not saved
-   [3-4)           syscall complete, results saved
-
-   Sometimes we never want to restart an interrupted syscall (because
-   sigaction says not to), so we only restart if "restart" is True.
-
-   This will also call VG_(post_syscall)() if the syscall has actually
-   completed (either because it was interrupted, or because it
-   actually finished).  It will not call VG_(post_syscall)() if the
-   syscall is set up for restart, which means that the pre-wrapper may
-   get called multiple times.
- */
-/* NB: this is identical to the amd64 version */
-void VGP_(interrupted_syscall)(ThreadId tid, 
-                               Word eip, UWord sysnum, UWord sysret,
-			       Bool restart)
-{
-   static const Bool debug = 0;
-
-   ThreadState *tst = VG_(get_ThreadState)(tid);
-   ThreadArchState *th_regs = &tst->arch;
-
-   if (debug)
-      VG_(printf)("interrupted_syscall: eip=%p; restart=%d eax=%d\n", 
-		  eip, restart, sysnum);
-
-   if (eip < VGA_(blksys_setup) || eip >= VGA_(blksys_finished)) {
-      VG_(printf)("  not in syscall (%p - %p)\n", VGA_(blksys_setup), VGA_(blksys_finished));
-      vg_assert(tst->syscallno == -1);
-      return;
-   }
-
-   vg_assert(tst->syscallno != -1);
-
-   if (eip >= VGA_(blksys_setup) && eip < VGA_(blksys_restart)) {
-      /* syscall hasn't even started; go around again */
-      if (debug)
-	 VG_(printf)("  not started: restart\n");
-      restart_syscall(th_regs);
-   } else if (eip == VGA_(blksys_restart)) {
-      /* We're either about to run the syscall, or it was interrupted
-	 and the kernel restarted it.  Restart if asked, otherwise
-	 EINTR it. */
-      if (restart)
-	 restart_syscall(th_regs);
-      else {
-	 th_regs->vex.VGP_SYSCALL_RET = -VKI_EINTR;
-	 VG_(post_syscall)(tid);
-      }
-   } else if (eip >= VGA_(blksys_complete) && eip < VGA_(blksys_committed)) {
-      /* Syscall complete, but result hasn't been written back yet.
-	 The saved real CPU %eax has the result, which we need to move
-	 to EAX. */
-      if (debug)
-	 VG_(printf)("  completed: ret=%d\n", sysret);
-      th_regs->vex.VGP_SYSCALL_RET = sysret;
-      VG_(post_syscall)(tid);
-   } else if (eip >= VGA_(blksys_committed) && eip < VGA_(blksys_finished)) {
-      /* Result committed, but the signal mask has not been restored;
-	 we expect our caller (the signal handler) will have fixed
-	 this up. */
-      if (debug)
-	 VG_(printf)("  all done\n");
-      VG_(post_syscall)(tid);
-   } else
-      VG_(core_panic)("?? strange syscall interrupt state?");
-   
-   tst->syscallno = -1;
-}
-
-extern void VGA_(_client_syscall)(Int syscallno, 
-                                  void* guest_state,
-				  const vki_sigset_t *syscall_mask,
-				  const vki_sigset_t *restore_mask,
-				  Int nsigwords);
-
-void VGA_(client_syscall)(Int syscallno, ThreadState *tst,
-			  const vki_sigset_t *syscall_mask)
-{
-   vki_sigset_t saved;
-   VGA_(_client_syscall)(syscallno, &tst->arch.vex, 
-                         syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord));
-}
-
-
 /* 
    Allocate a stack for this thread.
 
@@ -204,11 +82,11 @@
 			    -1, 0);
 
       if (stk != (void *)-1) {
-	 VG_(mprotect)(stk, VKI_PAGE_SIZE, VKI_PROT_NONE); /* guard page */
-	 tst->os_state.valgrind_stack_base = ((Addr)stk) + VKI_PAGE_SIZE;
-	 tst->os_state.valgrind_stack_szB  = STACK_SIZE_W * sizeof(UWord);
+         VG_(mprotect)(stk, VKI_PAGE_SIZE, VKI_PROT_NONE); /* guard page */
+         tst->os_state.valgrind_stack_base = ((Addr)stk) + VKI_PAGE_SIZE;
+         tst->os_state.valgrind_stack_szB  = STACK_SIZE_W * sizeof(UWord);
       } else 
-	 return (UWord*)-1;
+      return (UWord*)-1;
    }
 
    for (esp = (UWord*) tst->os_state.valgrind_stack_base;
@@ -361,9 +239,97 @@
    clone() handling
    ------------------------------------------------------------------ */
 
+/*
+        Perform a clone system call.  clone is strange because it has
+        fork()-like return-twice semantics, so it needs special
+        handling here.
+
+        Upon entry, we have:
+
+            int (fn)(void*)     in  0+FSZ(%esp)
+            void* child_stack   in  4+FSZ(%esp)
+            int flags           in  8+FSZ(%esp)
+            void* arg           in 12+FSZ(%esp)
+            pid_t* child_tid    in 16+FSZ(%esp)
+            pid_t* parent_tid   in 20+FSZ(%esp)
+            void* tls_ptr       in 24+FSZ(%esp)
+
+        System call requires:
+
+            int    $__NR_clone  in %eax
+            int    flags        in %ebx
+            void*  child_stack  in %ecx
+            pid_t* parent_tid   in %edx
+            pid_t* child_tid    in %edi
+            void*  tls_ptr      in %esi
+
+	Returns an Int encoded in the linux-x86 way, not a SysRes.
+ */
+#define STRINGIFZ(__str) #__str
+#define STRINGIFY(__str)  STRINGIFZ(__str)
+#define FSZ               "4+4+4" /* frame size = retaddr+ebx+edi */
+#define __NR_CLONE        STRINGIFY(__NR_clone)
+#define __NR_EXIT         STRINGIFY(__NR_exit)
+
+extern
+Int do_syscall_clone_x86_linux ( Int (*fn)(void *), 
+                                 void* stack, 
+                                 Int   flags, 
+                                 void* arg,
+                                 Int*  child_tid, 
+                                 Int*  parent_tid, 
+                                 vki_modify_ldt_t * );
+asm(
+"\n"
+"do_syscall_clone_x86_linux:\n"
+"        push    %ebx\n"
+"        push    %edi\n"
+
+         /* set up child stack with function and arg */
+"        movl     4+"FSZ"(%esp), %ecx\n"    /* syscall arg2: child stack */
+"        movl    12+"FSZ"(%esp), %ebx\n"    /* fn arg */
+"        movl     0+"FSZ"(%esp), %eax\n"    /* fn */
+"        lea     -8(%ecx), %ecx\n"          /* make space on stack */
+"        movl    %ebx, 4(%ecx)\n"           /*   fn arg */
+"        movl    %eax, 0(%ecx)\n"           /*   fn */
+
+         /* get other args to clone */
+"        movl     8+"FSZ"(%esp), %ebx\n"    /* syscall arg1: flags */
+"        movl    20+"FSZ"(%esp), %edx\n"    /* syscall arg3: parent tid * */
+"        movl    16+"FSZ"(%esp), %edi\n"    /* syscall arg4: child tid * */
+"        movl    24+"FSZ"(%esp), %esi\n"    /* syscall arg5: tls_ptr * */
+"        movl    $"__NR_CLONE", %eax\n"
+"        int     $0x80\n"                   /* clone() */
+"        testl   %eax, %eax\n"              /* child if retval == 0 */
+"        jnz     1f\n"
+
+         /* CHILD - call thread function */
+"        popl    %eax\n"
+"        call    *%eax\n"                   /* call fn */
+
+         /* exit with result */
+"        movl    %eax, %ebx\n"              /* arg1: return value from fn */
+"        movl    $"__NR_EXIT", %eax\n"
+"        int     $0x80\n"
+
+         /* Hm, exit returned */
+"        ud2\n"
+
+"1:      /* PARENT or ERROR */\n"
+"        pop     %edi\n"
+"        pop     %ebx\n"
+"        ret\n"
+);
+
+#undef FSZ
+#undef __NR_CLONE
+#undef __NR_EXIT
+#undef STRINGIFY
+#undef STRINGIFZ
+
 // forward declarations
 static void setup_child ( ThreadArchState*, ThreadArchState*, Bool );
-static Int sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
+static SysRes sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
 
 /* 
    When a client clones, we need to keep track of the new thread.  This means:
@@ -375,20 +341,21 @@
    but using the scheduler entrypoint for EIP, and a separate stack
    for ESP.
  */
-static Int do_clone(ThreadId ptid, 
-		    UInt flags, Addr esp, 
-		    Int *parent_tidptr, 
-		    Int *child_tidptr, 
-		    vki_modify_ldt_t *tlsinfo)
+static SysRes do_clone ( ThreadId ptid, 
+                         UInt flags, Addr esp, 
+                         Int *parent_tidptr, 
+                         Int *child_tidptr, 
+                         vki_modify_ldt_t *tlsinfo)
 {
    static const Bool debug = False;
 
-   ThreadId ctid = VG_(alloc_ThreadState)();
-   ThreadState *ptst = VG_(get_ThreadState)(ptid);
-   ThreadState *ctst = VG_(get_ThreadState)(ctid);
-   UWord *stack;
-   Segment *seg;
-   Int ret;
+   ThreadId     ctid = VG_(alloc_ThreadState)();
+   ThreadState* ptst = VG_(get_ThreadState)(ptid);
+   ThreadState* ctst = VG_(get_ThreadState)(ctid);
+   UWord*       stack;
+   Segment*     seg;
+   SysRes       res;
+   Int          eax;
    vki_sigset_t blockall, savedmask;
 
    VG_(sigfillset)(&blockall);
@@ -416,7 +383,9 @@
       is passed as an arg to setup_child. */
    setup_child( &ctst->arch, &ptst->arch, True /*VG_(clo_support_elan3)*/ );
 
-   VGP_SET_SYSCALL_RESULT(ctst->arch, 0);
+   /* Make sys_clone appear to have returned zero in the child. */
+   ctst->arch.vex.guest_EAX = 0;
+
    if (esp != 0)
       ctst->arch.vex.guest_ESP = esp;
 
@@ -447,13 +416,14 @@
 
    if (flags & VKI_CLONE_SETTLS) {
       if (debug)
-	 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d base=%p limit=%x; esp=%p fs=%x gs=%x\n",
-		     tlsinfo, tlsinfo->entry_number, tlsinfo->base_addr, tlsinfo->limit,
+	 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d "
+                     "base=%p limit=%x; esp=%p fs=%x gs=%x\n",
+		     tlsinfo, tlsinfo->entry_number, 
+                     tlsinfo->base_addr, tlsinfo->limit,
 		     ptst->arch.vex.guest_ESP,
 		     ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
-      ret = sys_set_thread_area(ctid, tlsinfo);
-
-      if (ret != 0)
+      res = sys_set_thread_area(ctid, tlsinfo);
+      if (res.isError)
 	 goto out;
    }
 
@@ -463,30 +433,37 @@
    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
 
    /* Create the new thread */
-   ret = VG_(clone)(start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
-		    child_tidptr, parent_tidptr, NULL);
-
+   eax = do_syscall_clone_x86_linux(
+            start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
+            child_tidptr, parent_tidptr, NULL
+         );
+   res = VG_(mk_SysRes_x86_linux)( eax );
    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
 
   out:
-   if (ret < 0) {
+   if (res.isError) {
       /* clone failed */
       VGP_(cleanup_thread)(&ctst->arch);
       ctst->status = VgTs_Empty;
    }
 
-   return ret;
+   return res;
 }
 
+
 /* Do a clone which is really a fork() */
-static Int do_fork_clone(ThreadId tid, UInt flags, Addr esp, Int *parent_tidptr, Int *child_tidptr)
+static SysRes do_fork_clone ( ThreadId tid, 
+                              UInt flags, Addr esp, 
+                              Int* parent_tidptr, 
+                              Int* child_tidptr )
 {
    vki_sigset_t fork_saved_mask;
    vki_sigset_t mask;
-   Int ret;
+   SysRes       res;
 
-   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM | VKI_CLONE_FILES | VKI_CLONE_VFORK))
-      return -VKI_EINVAL;
+   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM 
+                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
 
    /* Block all signals during fork, so that we can fix things up in
       the child without being interrupted. */
@@ -497,19 +474,22 @@
 
    /* Since this is the fork() form of clone, we don't need all that
       VG_(clone) stuff */
-   ret = VG_(do_syscall5)(__NR_clone, flags, (UWord)NULL, (UWord)parent_tidptr, 
+   res = VG_(do_syscall5)(__NR_clone, flags, (UWord)NULL, (UWord)parent_tidptr, 
                                              (UWord)NULL, (UWord)child_tidptr);
 
-   if (ret == 0) {
+   if (!res.isError && res.val == 0) {
       /* child */
       VG_(do_atfork_child)(tid);
 
       /* restore signal mask */
       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-   } else if (ret > 0) {
+   } 
+   else 
+   if (!res.isError && res.val > 0) {
       /* parent */
       if (VG_(clo_trace_syscalls))
-	  VG_(printf)("   clone(fork): process %d created child %d\n", VG_(getpid)(), ret);
+	  VG_(printf)("   clone(fork): process %d created child %d\n", 
+                      VG_(getpid)(), res.val);
 
       VG_(do_atfork_parent)(tid);
 
@@ -517,7 +497,7 @@
       VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
    }
 
-   return ret;
+   return res;
 }
 
 /* ---------------------------------------------------------------------
@@ -585,7 +565,7 @@
 
 static
 void translate_to_hw_format ( /* IN  */ vki_modify_ldt_t* inn,
-			      /* OUT */ VexGuestX86SegDescr* out,
+                              /* OUT */ VexGuestX86SegDescr* out,
                                         Int oldmode )
 {
    UInt entry_1, entry_2;
@@ -655,22 +635,22 @@
 static void copy_LDT_from_to ( VexGuestX86SegDescr* src,
                                VexGuestX86SegDescr* dst )
 {
-  Int i;
-  vg_assert(src);
-  vg_assert(dst);
-  for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
-     dst[i] = src[i];
+   Int i;
+   vg_assert(src);
+   vg_assert(dst);
+   for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
+      dst[i] = src[i];
 }
 
 /* Copy contents between two existing GDTs. */
 static void copy_GDT_from_to ( VexGuestX86SegDescr* src,
                                VexGuestX86SegDescr* dst )
 {
-  Int i;
-  vg_assert(src);
-  vg_assert(dst);
-  for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
-     dst[i] = src[i];
+   Int i;
+   vg_assert(src);
+   vg_assert(dst);
+   for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
+      dst[i] = src[i];
 }
 
 /* Free this thread's DTs, if it has any. */
@@ -709,9 +689,9 @@
  * the security checks done on new descriptors.
  */
 static
-Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
+SysRes read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
 {
-   Int    err;
+   SysRes res;
    UInt   i, size;
    UChar* ldt;
 
@@ -723,7 +703,7 @@
    vg_assert(8 == sizeof(VexGuestX86SegDescr));
 
    ldt = (Char*)(VG_(threads)[tid].arch.vex.guest_LDT);
-   err = 0;
+   res = VG_(mk_SysRes_Success)( 0 );
    if (ldt == NULL)
       /* LDT not allocated, meaning all entries are null */
       goto out;
@@ -732,19 +712,19 @@
    if (size > bytecount)
       size = bytecount;
 
-   err = size;
+   res = VG_(mk_SysRes_Success)( size );
    for (i = 0; i < size; i++)
       ptr[i] = ldt[i];
 
   out:
-   return err;
+   return res;
 }
 
 
 static
-Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
+SysRes write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
 {
-   Int error;
+   SysRes res;
    VexGuestX86SegDescr* ldt;
    vki_modify_ldt_t* ldt_info; 
 
@@ -759,11 +739,11 @@
    ldt      = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_LDT;
    ldt_info = (vki_modify_ldt_t*)ptr;
 
-   error = -VKI_EINVAL;
+   res = VG_(mk_SysRes_Error)( VKI_EINVAL );
    if (bytecount != sizeof(vki_modify_ldt_t))
       goto out;
 
-   error = -VKI_EINVAL;
+   res = VG_(mk_SysRes_Error)( VKI_EINVAL );
    if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
       goto out;
    if (ldt_info->contents == 3) {
@@ -782,17 +762,17 @@
 
    /* Install the new entry ...  */
    translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
-   error = 0;
+   res = VG_(mk_SysRes_Success)( 0 );
 
   out:
-   return error;
+   return res;
 }
 
 
-static Int sys_modify_ldt ( ThreadId tid,
-                            Int func, void* ptr, UInt bytecount )
+static SysRes sys_modify_ldt ( ThreadId tid,
+                               Int func, void* ptr, UInt bytecount )
 {
-   Int ret = -VKI_ENOSYS;
+   SysRes ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
 
    switch (func) {
    case 0:
@@ -815,16 +795,16 @@
 }
 
 
-static Int sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
+static SysRes sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
 {
-   Int idx;
+   Int                  idx;
    VexGuestX86SegDescr* gdt;
 
    vg_assert(8 == sizeof(VexGuestX86SegDescr));
    vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
 
    if (info == NULL)
-      return -VKI_EFAULT;
+      return VG_(mk_SysRes_Error)( VKI_EFAULT );
 
    gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
 
@@ -845,9 +825,9 @@
       }
 
       if (idx == VEX_GUEST_X86_GDT_NENT)
-         return -VKI_ESRCH;
+         return VG_(mk_SysRes_Error)( VKI_ESRCH );
    } else if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
-      return -VKI_EINVAL;
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
    }
 
    translate_to_hw_format(info, &gdt[idx], 0);
@@ -859,49 +839,49 @@
    VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
              (Addr) & info->entry_number, sizeof(unsigned int) );
 
-   return 0;
+   return VG_(mk_SysRes_Success)( 0 );
 }
 
 
-static Int sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
-{
-   Int idx;
-   VexGuestX86SegDescr* gdt;
-
-   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
-   vg_assert(8 == sizeof(VexGuestX86SegDescr));
-
-   if (info == NULL)
-      return -VKI_EFAULT;
-
-   idx = info->entry_number;
-
-   if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
-      return -VKI_EINVAL;
-
-   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
-
-   /* If the thread doesn't have a GDT, allocate it now. */
-   if (!gdt) {
-      gdt = alloc_zeroed_x86_GDT();
-      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
-   }
-
-   info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
-                     ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
-                     gdt[idx].LdtEnt.Bits.BaseLow;
-   info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
-                   gdt[idx].LdtEnt.Bits.LimitLow;
-   info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
-   info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
-   info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
-   info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
-   info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
-   info->useable = gdt[idx].LdtEnt.Bits.Sys;
-   info->reserved = 0;
-
-   return 0;
-}
+//zz static Int sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
+//zz {
+//zz    Int idx;
+//zz    VexGuestX86SegDescr* gdt;
+//zz 
+//zz    vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
+//zz    vg_assert(8 == sizeof(VexGuestX86SegDescr));
+//zz 
+//zz    if (info == NULL)
+//zz       return -VKI_EFAULT;
+//zz 
+//zz    idx = info->entry_number;
+//zz 
+//zz    if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
+//zz       return -VKI_EINVAL;
+//zz 
+//zz    gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
+//zz 
+//zz    /* If the thread doesn't have a GDT, allocate it now. */
+//zz    if (!gdt) {
+//zz       gdt = alloc_zeroed_x86_GDT();
+//zz       VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
+//zz    }
+//zz 
+//zz    info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
+//zz                      ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
+//zz                      gdt[idx].LdtEnt.Bits.BaseLow;
+//zz    info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
+//zz                    gdt[idx].LdtEnt.Bits.LimitLow;
+//zz    info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
+//zz    info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
+//zz    info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
+//zz    info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
+//zz    info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
+//zz    info->useable = gdt[idx].LdtEnt.Bits.Sys;
+//zz    info->reserved = 0;
+//zz 
+//zz    return 0;
+//zz }
 
 /* ---------------------------------------------------------------------
    More thread stuff
@@ -946,50 +926,64 @@
    }
 }  
 
+
 /* ---------------------------------------------------------------------
    PRE/POST wrappers for x86/Linux-specific syscalls
    ------------------------------------------------------------------ */
 
-// Nb: See the comment above the generic PRE/POST wrappers in
-// coregrind/vg_syscalls.c for notes about how they work.
+#define PRE(name)       DEFN_PRE_TEMPLATE(x86_linux, name)
+#define POST(name)      DEFN_POST_TEMPLATE(x86_linux, name)
 
-#define PRE(name, f)     PRE_TEMPLATE(static, x86_linux, name, f)
-#define POST(name)      POST_TEMPLATE(static, x86_linux, name)
+/* Add prototypes for the wrappers declared here, so that gcc doesn't
+   harass us for not having prototypes.  Really this is a kludge --
+   the right thing to do is to make these wrappers 'static' since they
+   aren't visible outside this file, but that requires even more macro
+   magic. */
+DECL_TEMPLATE(x86_linux, sys_socketcall);
+DECL_TEMPLATE(x86_linux, sys_stat64);
+DECL_TEMPLATE(x86_linux, sys_fstat64);
+DECL_TEMPLATE(x86_linux, sys_lstat64);
+DECL_TEMPLATE(x86_linux, sys_clone);
+DECL_TEMPLATE(x86_linux, old_mmap);
+DECL_TEMPLATE(x86_linux, sys_sigreturn);
+DECL_TEMPLATE(x86_linux, sys_ipc);
+DECL_TEMPLATE(x86_linux, sys_rt_sigreturn);
+DECL_TEMPLATE(x86_linux, sys_modify_ldt);
 
-PRE(old_select, MayBlock)
-{
-   /* struct sel_arg_struct {
-      unsigned long n;
-      fd_set *inp, *outp, *exp;
-      struct timeval *tvp;
-      };
-   */
-   PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
-   PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
+//zz PRE(old_select, MayBlock)
+//zz {
+//zz    /* struct sel_arg_struct {
+//zz       unsigned long n;
+//zz       fd_set *inp, *outp, *exp;
+//zz       struct timeval *tvp;
+//zz       };
+//zz    */
+//zz    PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
+//zz    PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
+//zz 
+//zz    {
+//zz       UInt* arg_struct = (UInt*)ARG1;
+//zz       UInt a1, a2, a3, a4, a5;
+//zz 
+//zz       a1 = arg_struct[0];
+//zz       a2 = arg_struct[1];
+//zz       a3 = arg_struct[2];
+//zz       a4 = arg_struct[3];
+//zz       a5 = arg_struct[4];
+//zz 
+//zz       PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
+//zz       if (a2 != (Addr)NULL)
+//zz          PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
+//zz       if (a3 != (Addr)NULL)
+//zz          PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
+//zz       if (a4 != (Addr)NULL)
+//zz          PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
+//zz       if (a5 != (Addr)NULL)
+//zz          PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
+//zz    }
+//zz }
 
-   {
-      UInt* arg_struct = (UInt*)ARG1;
-      UInt a1, a2, a3, a4, a5;
-
-      a1 = arg_struct[0];
-      a2 = arg_struct[1];
-      a3 = arg_struct[2];
-      a4 = arg_struct[3];
-      a5 = arg_struct[4];
-
-      PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
-      if (a2 != (Addr)NULL)
-	 PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
-      if (a3 != (Addr)NULL)
-	 PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
-      if (a4 != (Addr)NULL)
-	 PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
-      if (a5 != (Addr)NULL)
-	 PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
-   }
-}
-
-PRE(sys_clone, Special)
+PRE(sys_clone)
 {
    UInt cloneflags;
 
@@ -1004,21 +998,21 @@
    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
       if (!VG_(is_addressable)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
-         SET_RESULT( -VKI_EFAULT );
+         SET_STATUS_Failure( VKI_EFAULT );
          return;
       }
    }
    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
       if (!VG_(is_addressable)(ARG5, sizeof(Int), VKI_PROT_WRITE)) {
-         SET_RESULT( -VKI_EFAULT );
+         SET_STATUS_Failure( VKI_EFAULT );
          return;
       }
    }
    if (ARG1 & VKI_CLONE_SETTLS) {
       PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
       if (!VG_(is_addressable)(ARG4, sizeof(vki_modify_ldt_t), VKI_PROT_READ)) {
-         SET_RESULT( -VKI_EFAULT );
+         SET_STATUS_Failure( VKI_EFAULT );
          return;
       }
    }
@@ -1026,7 +1020,7 @@
    cloneflags = ARG1;
 
    if (!VG_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
-      SET_RESULT( -VKI_EINVAL );
+      SET_STATUS_Failure( VKI_EINVAL );
       return;
    }
 
@@ -1040,6 +1034,7 @@
    if (
           (cloneflags == 0x100011 || cloneflags == 0x1200011
                                   || cloneflags == 0x7D0F00
+                                  || cloneflags == 0x790F00
                                   || cloneflags == 0x3D0F00
                                   || cloneflags == 0xF00
                                   || cloneflags == 0xF21)) {
@@ -1051,15 +1046,17 @@
    }
 
    /* Only look at the flags we really care about */
-   switch(cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
+   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 
+                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
       /* thread creation */
-      SET_RESULT(do_clone(tid,
-                          ARG1,         /* flags */
-                          (Addr)ARG2,   /* child ESP */
-                          (Int *)ARG3,  /* parent_tidptr */
-                          (Int *)ARG5,  /* child_tidptr */
-                          (vki_modify_ldt_t *)ARG4)); /* set_tls */
+      SET_STATUS_from_SysRes(
+         do_clone(tid,
+                  ARG1,         /* flags */
+                  (Addr)ARG2,   /* child ESP */
+                  (Int *)ARG3,  /* parent_tidptr */
+                  (Int *)ARG5,  /* child_tidptr */
+                  (vki_modify_ldt_t *)ARG4)); /* set_tls */
       break;
 
    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
@@ -1067,11 +1064,12 @@
       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
 
    case 0: /* plain fork */
-      SET_RESULT(do_fork_clone(tid,
-                               cloneflags,              /* flags */
-                               (Addr)ARG2,      /* child ESP */
-                               (Int *)ARG3,     /* parent_tidptr */
-                               (Int *)ARG5));   /* child_tidptr */
+      SET_STATUS_from_SysRes(
+         do_fork_clone(tid,
+                       cloneflags,              /* flags */
+                       (Addr)ARG2,      /* child ESP */
+                       (Int *)ARG3,     /* parent_tidptr */
+                       (Int *)ARG5));   /* child_tidptr */
       break;
 
    default:
@@ -1094,7 +1092,7 @@
          ("Valgrind does not support general clone().");
    }
 
-   if (!VG_(is_kerror)(RES)) {
+   if (SUCCESS) {
       if (ARG1 & VKI_CLONE_PARENT_SETTID)
          POST_MEM_WRITE(ARG3, sizeof(Int));
       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
@@ -1102,53 +1100,77 @@
 
       /* Thread creation was successful; let the child have the chance
          to run */
-      VG_(vg_yield)();
+      *flags |= SfYieldAfter;
    }
 }
 
-PRE(sys_sigreturn, Special)
+PRE(sys_sigreturn)
 {
+   ThreadState* tst;
    PRINT("sigreturn ( )");
 
+   vg_assert(VG_(is_valid_tid)(tid));
+   vg_assert(tid >= 1 && tid < VG_N_THREADS);
+   vg_assert(VG_(is_running_thread)(tid));
+
    /* Adjust esp to point to start of frame; skip back up over
       sigreturn sequence's "popl %eax" and handler ret addr */
+   tst = VG_(get_ThreadState)(tid);
    tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
 
    /* This is only so that the EIP is (might be) useful to report if
       something goes wrong in the sigreturn */
-   restart_syscall(&tst->arch);
+   VG_(fixup_guest_state_to_restart_syscall)(&tst->arch);
 
    VG_(sigframe_destroy)(tid, False);
 
-   /* Keep looking for signals until there are none */
-   VG_(poll_signals)(tid);
+   /* For unclear reasons, it appears we need the syscall to return
+      without changing %EAX.  Since %EAX is the return value, and can
+      denote either success or failure, we must set up so that the
+      driver logic copies it back unchanged.  Also, note %EAX is of
+      the guest registers written by VG_(sigframe_destroy). */
+   SET_STATUS_from_SysRes(
+      VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) 
+   );
 
-   /* placate return-must-be-set assertion */
-   SET_RESULT(RES);
+   /* Check to see if some any signals arose as a result of this. */
+   *flags |= SfPollAfter;
 }
 
-PRE(sys_rt_sigreturn, Special)
+PRE(sys_rt_sigreturn)
 {
+   ThreadState* tst;
    PRINT("rt_sigreturn ( )");
 
+   vg_assert(VG_(is_valid_tid)(tid));
+   vg_assert(tid >= 1 && tid < VG_N_THREADS);
+   vg_assert(VG_(is_running_thread)(tid));
+
    /* Adjust esp to point to start of frame; skip back up over handler
       ret addr */
+   tst = VG_(get_ThreadState)(tid);
    tst->arch.vex.guest_ESP -= sizeof(Addr);
 
    /* This is only so that the EIP is (might be) useful to report if
       something goes wrong in the sigreturn */
-   restart_syscall(&tst->arch);
+   VG_(fixup_guest_state_to_restart_syscall)(&tst->arch);
 
    VG_(sigframe_destroy)(tid, True);
 
-   /* Keep looking for signals until there are none */
-   VG_(poll_signals)(tid);
+   /* For unclear reasons, it appears we need the syscall to return
+      without changing %EAX.  Since %EAX is the return value, and can
+      denote either success or failure, we must set up so that the
+      driver logic copies it back unchanged.  Also, note %EAX is of
+      the guest registers written by VG_(sigframe_destroy). */
+   SET_STATUS_from_SysRes(
+      VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) 
+   );
 
-   /* placate return-must-be-set assertion */
-   SET_RESULT(RES);
+   /* Check to see if some any signals arose as a result of this. */
+   *flags |= SfPollAfter;
 }
 
-PRE(sys_modify_ldt, Special)
+PRE(sys_modify_ldt)
 {
    PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
    PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
@@ -1163,101 +1185,101 @@
       PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
    }
    /* "do" the syscall ourselves; the kernel never sees it */
-   SET_RESULT( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
+   SET_STATUS_from_SysRes( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
 
-   if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
+   if (ARG1 == 0 && SUCCESS && RES > 0) {
       POST_MEM_WRITE( ARG2, RES );
    }
 }
 
-PRE(sys_set_thread_area, Special)
-{
-   PRINT("sys_set_thread_area ( %p )", ARG1);
-   PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
-   PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
-
-   /* "do" the syscall ourselves; the kernel never sees it */
-   SET_RESULT( sys_set_thread_area( tid, (void *)ARG1 ) );
-}
-
-PRE(sys_get_thread_area, Special)
-{
-   PRINT("sys_get_thread_area ( %p )", ARG1);
-   PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
-   PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
-
-   /* "do" the syscall ourselves; the kernel never sees it */
-   SET_RESULT( sys_get_thread_area( tid, (void *)ARG1 ) );
-
-   if (!VG_(is_kerror)(RES)) {
-      POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
-   }
-}
-
-// Parts of this are x86-specific, but the *PEEK* cases are generic.
-// XXX: Why is the memory pointed to by ARG3 never checked?
-PRE(sys_ptrace, 0)
-{
-   PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
-   PRE_REG_READ4(int, "ptrace", 
-                 long, request, long, pid, long, addr, long, data);
-   switch (ARG1) {
-   case VKI_PTRACE_PEEKTEXT:
-   case VKI_PTRACE_PEEKDATA:
-   case VKI_PTRACE_PEEKUSR:
-      PRE_MEM_WRITE( "ptrace(peek)", ARG4, 
-		     sizeof (long));
-      break;
-   case VKI_PTRACE_GETREGS:
-      PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 
-		     sizeof (struct vki_user_regs_struct));
-      break;
-   case VKI_PTRACE_GETFPREGS:
-      PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 
-		     sizeof (struct vki_user_i387_struct));
-      break;
-   case VKI_PTRACE_GETFPXREGS:
-      PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4, 
-                     sizeof(struct vki_user_fxsr_struct) );
-      break;
-   case VKI_PTRACE_SETREGS:
-      PRE_MEM_READ( "ptrace(setregs)", ARG4, 
-		     sizeof (struct vki_user_regs_struct));
-      break;
-   case VKI_PTRACE_SETFPREGS:
-      PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 
-		     sizeof (struct vki_user_i387_struct));
-      break;
-   case VKI_PTRACE_SETFPXREGS:
-      PRE_MEM_READ( "ptrace(setfpxregs)", ARG4, 
-                     sizeof(struct vki_user_fxsr_struct) );
-      break;
-   default:
-      break;
-   }
-}
-
-POST(sys_ptrace)
-{
-   switch (ARG1) {
-   case VKI_PTRACE_PEEKTEXT:
-   case VKI_PTRACE_PEEKDATA:
-   case VKI_PTRACE_PEEKUSR:
-      POST_MEM_WRITE( ARG4, sizeof (long));
-      break;
-   case VKI_PTRACE_GETREGS:
-      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
-      break;
-   case VKI_PTRACE_GETFPREGS:
-      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
-      break;
-   case VKI_PTRACE_GETFPXREGS:
-      POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
-      break;
-   default:
-      break;
-   }
-}
+//zz PRE(sys_set_thread_area, Special)
+//zz {
+//zz    PRINT("sys_set_thread_area ( %p )", ARG1);
+//zz    PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
+//zz    PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
+//zz 
+//zz    /* "do" the syscall ourselves; the kernel never sees it */
+//zz    SET_STATUS_( sys_set_thread_area( tid, (void *)ARG1 ) );
+//zz }
+//zz 
+//zz PRE(sys_get_thread_area, Special)
+//zz {
+//zz    PRINT("sys_get_thread_area ( %p )", ARG1);
+//zz    PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
+//zz    PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
+//zz 
+//zz    /* "do" the syscall ourselves; the kernel never sees it */
+//zz    SET_STATUS_( sys_get_thread_area( tid, (void *)ARG1 ) );
+//zz 
+//zz    if (!VG_(is_kerror)(RES)) {
+//zz       POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
+//zz    }
+//zz }
+//zz 
+//zz // Parts of this are x86-specific, but the *PEEK* cases are generic.
+//zz // XXX: Why is the memory pointed to by ARG3 never checked?
+//zz PRE(sys_ptrace, 0)
+//zz {
+//zz    PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
+//zz    PRE_REG_READ4(int, "ptrace", 
+//zz                  long, request, long, pid, long, addr, long, data);
+//zz    switch (ARG1) {
+//zz    case VKI_PTRACE_PEEKTEXT:
+//zz    case VKI_PTRACE_PEEKDATA:
+//zz    case VKI_PTRACE_PEEKUSR:
+//zz       PRE_MEM_WRITE( "ptrace(peek)", ARG4, 
+//zz 		     sizeof (long));
+//zz       break;
+//zz    case VKI_PTRACE_GETREGS:
+//zz       PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 
+//zz 		     sizeof (struct vki_user_regs_struct));
+//zz       break;
+//zz    case VKI_PTRACE_GETFPREGS:
+//zz       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 
+//zz 		     sizeof (struct vki_user_i387_struct));
+//zz       break;
+//zz    case VKI_PTRACE_GETFPXREGS:
+//zz       PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4, 
+//zz                      sizeof(struct vki_user_fxsr_struct) );
+//zz       break;
+//zz    case VKI_PTRACE_SETREGS:
+//zz       PRE_MEM_READ( "ptrace(setregs)", ARG4, 
+//zz 		     sizeof (struct vki_user_regs_struct));
+//zz       break;
+//zz    case VKI_PTRACE_SETFPREGS:
+//zz       PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 
+//zz 		     sizeof (struct vki_user_i387_struct));
+//zz       break;
+//zz    case VKI_PTRACE_SETFPXREGS:
+//zz       PRE_MEM_READ( "ptrace(setfpxregs)", ARG4, 
+//zz                      sizeof(struct vki_user_fxsr_struct) );
+//zz       break;
+//zz    default:
+//zz       break;
+//zz    }
+//zz }
+//zz 
+//zz POST(sys_ptrace)
+//zz {
+//zz    switch (ARG1) {
+//zz    case VKI_PTRACE_PEEKTEXT:
+//zz    case VKI_PTRACE_PEEKDATA:
+//zz    case VKI_PTRACE_PEEKUSR:
+//zz       POST_MEM_WRITE( ARG4, sizeof (long));
+//zz       break;
+//zz    case VKI_PTRACE_GETREGS:
+//zz       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
+//zz       break;
+//zz    case VKI_PTRACE_GETFPREGS:
+//zz       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
+//zz       break;
+//zz    case VKI_PTRACE_GETFPXREGS:
+//zz       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
+//zz       break;
+//zz    default:
+//zz       break;
+//zz    }
+//zz }
 
 // XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk
 static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
@@ -1268,7 +1290,7 @@
 }
  
 // XXX: should use the constants here (eg. SHMAT), not the numbers directly!
-PRE(sys_ipc, 0)
+PRE(sys_ipc)
 {
    PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
    // XXX: this is simplistic -- some args are not used in all circumstances.
@@ -1279,7 +1301,7 @@
    switch (ARG1 /* call */) {
    case VKI_SEMOP:
       VG_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
-      /* tst->sys_flags |= MayBlock; */
+      *flags |= SfMayBlock;
       break;
    case VKI_SEMGET:
       break;
@@ -1291,13 +1313,12 @@
    }
    case VKI_SEMTIMEDOP:
       VG_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
-      /* tst->sys_flags |= MayBlock; */
+      *flags |= SfMayBlock;
       break;
    case VKI_MSGSND:
       VG_(generic_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
-      /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
-            tst->sys_flags |= MayBlock;
-      */
+      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+         *flags |= SfMayBlock;
       break;
    case VKI_MSGRCV:
    {
@@ -1313,9 +1334,8 @@
 
       VG_(generic_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
 
-      /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
-            tst->sys_flags |= MayBlock;
-      */
+      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+         *flags |= SfMayBlock;
       break;
    }
    case VKI_MSGGET:
@@ -1324,14 +1344,19 @@
       VG_(generic_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
       break;
    case VKI_SHMAT:
+   {
+      UWord w;
       PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
-      ARG5 = VG_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
-      if (ARG5 == 0)
-         SET_RESULT( -VKI_EINVAL );
+      w = VG_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
+      if (w == 0)
+         SET_STATUS_Failure( VKI_EINVAL );
+      else
+         ARG5 = w;
       break;
+   }
    case VKI_SHMDT:
       if (!VG_(generic_PRE_sys_shmdt)(tid, ARG5))
-	 SET_RESULT( -VKI_EINVAL );
+	 SET_STATUS_Failure( VKI_EINVAL );
       break;
    case VKI_SHMGET:
       break;
@@ -1347,6 +1372,7 @@
 
 POST(sys_ipc)
 {
+   vg_assert(SUCCESS);
    switch (ARG1 /* call */) {
    case VKI_SEMOP:
    case VKI_SEMGET:
@@ -1412,90 +1438,471 @@
    }
 }
 
-
-// jrs 20050207: this is from the svn branch
-//PRE(sys_sigaction, Special)
-//{
-//   PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
-//   PRE_REG_READ3(int, "sigaction",
-//                 int, signum, const struct old_sigaction *, act,
-//                 struct old_sigaction *, oldact)
-//   if (ARG2 != 0)
-//      PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
-//   if (ARG3 != 0)
-//      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
-//
-//   VG_(do_sys_sigaction)(tid);
-//}
-
-/* Convert from non-RT to RT sigset_t's */
-static void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
+PRE(old_mmap)
 {
-   VG_(sigemptyset)(set);
-   set->sig[0] = *oldset;
+   /* struct mmap_arg_struct {           
+         unsigned long addr;
+         unsigned long len;
+         unsigned long prot;
+         unsigned long flags;
+         unsigned long fd;
+         unsigned long offset;
+   }; */
+   UWord a1, a2, a3, a4, a5, a6;
+
+   UWord* arg_block = (UWord*)ARG1;
+   PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, ARG1);
+   PRE_MEM_READ( "old_mmap(args)", (Addr)arg_block, 6*sizeof(UWord) );
+
+   a1 = arg_block[0];
+   a2 = arg_block[1];
+   a3 = arg_block[2];
+   a4 = arg_block[3];
+   a5 = arg_block[4];
+   a6 = arg_block[5];
+
+   PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
+         a1, (ULong)a2, a3, a4, a5, a6 );
+
+   if (a2 == 0) {
+      /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
+         shall be established. */
+      SET_STATUS_Failure( VKI_EINVAL );
+      return;
+   }
+
+   if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
+      /* zap any misaligned addresses. */
+      SET_STATUS_Failure( VKI_EINVAL );
+      return;
+   }
+
+   if (a4 & VKI_MAP_FIXED) {
+      if (!VG_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
+         PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
+         SET_STATUS_Failure( VKI_ENOMEM );
+      }
+   } else {
+      Addr a = VG_(find_map_space)(a1, a2, True);
+      if (0) VG_(printf)("find_map_space(%p, %d) -> %p\n",a1,a2,a);
+      if (a == 0 && a1 != 0) {
+         a1 = VG_(find_map_space)(0, a2, True);
+      }
+      else
+         a1 = a;
+      if (a1 == 0)
+         SET_STATUS_Failure( VKI_ENOMEM );
+      else
+         a4 |= VKI_MAP_FIXED;
+   }
+
+   if (! FAILURE) {
+      SysRes res = VG_(mmap_native)((void*)a1, a2, a3, a4, a5, a6);
+      SET_STATUS_from_SysRes(res);
+      if (!res.isError) {
+         vg_assert(VG_(valid_client_addr)(res.val, a2, tid, "old_mmap"));
+         VG_(mmap_segment)( (Addr)res.val, a2, a3, a4, a5, a6 );
+      }
+   }
+
+   if (0)
+   VG_(printf)("old_mmap( %p, fixed %d ) -> %s(%p)\n", 
+               arg_block[0], 
+               arg_block[3]&VKI_MAP_FIXED, 
+               FAILURE ? "Fail" : "Success", RES_unchecked);
+
+   /* Stay sane */
+   if (SUCCESS && (arg_block[3] & VKI_MAP_FIXED))
+      vg_assert(RES == arg_block[0]);
 }
-PRE(sys_sigaction, Special)
+
+// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
+// applicable to every architecture -- I think only to 32-bit archs.
+// We're going to need something like linux/core_os32.h for such
+// things, eventually, I think.  --njn
+PRE(sys_lstat64)
 {
-   struct vki_sigaction new, old;
-   struct vki_sigaction *newp, *oldp;
+   PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
+   PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
+   PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
+   PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
+}
 
-   PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
-   PRE_REG_READ3(int, "sigaction",
-                 int, signum, const struct old_sigaction *, act,
-                 struct old_sigaction *, oldact);
-
-   newp = oldp = NULL;
-
-   if (ARG2 != 0)
-      PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
-
-   if (ARG3 != 0) {
-      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
-      oldp = &old;
-   }
-
-   //jrs 20050207: what?!  how can this make any sense?
-   //if (VG_(is_kerror)(SYSRES))
-   //   return;
-
-   if (ARG2 != 0) {
-      struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
-
-      new.ksa_handler = oldnew->ksa_handler;
-      new.sa_flags = oldnew->sa_flags;
-      new.sa_restorer = oldnew->sa_restorer;
-      convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
-      newp = &new;
-   }
-
-   SET_RESULT( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
-
-   if (ARG3 != 0 && RES == 0) {
-      struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
-
-      oldold->ksa_handler = oldp->ksa_handler;
-      oldold->sa_flags = oldp->sa_flags;
-      oldold->sa_restorer = oldp->sa_restorer;
-      oldold->sa_mask = oldp->sa_mask.sig[0];
+POST(sys_lstat64)
+{
+   vg_assert(SUCCESS);
+   if (RES == 0) {
+      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
    }
 }
 
-POST(sys_sigaction)
+PRE(sys_stat64)
 {
-   if (RES == 0 && ARG3 != 0)
-      POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
+   PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
+   PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
+   PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
+   PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
 }
 
-#undef PRE
-#undef POST
+POST(sys_stat64)
+{
+   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+}
+
+PRE(sys_fstat64)
+{
+   PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
+   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
+   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
+}
+
+POST(sys_fstat64)
+{
+   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
+}
+
+PRE(sys_socketcall)
+{
+#  define ARG2_0  (((UWord*)ARG2)[0])
+#  define ARG2_1  (((UWord*)ARG2)[1])
+#  define ARG2_2  (((UWord*)ARG2)[2])
+#  define ARG2_3  (((UWord*)ARG2)[3])
+#  define ARG2_4  (((UWord*)ARG2)[4])
+#  define ARG2_5  (((UWord*)ARG2)[5])
+
+   *flags |= SfMayBlock;
+   PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
+   PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
+
+   switch (ARG1 /* request */) {
+
+   case VKI_SYS_SOCKETPAIR:
+      /* int socketpair(int d, int type, int protocol, int sv[2]); */
+      PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
+      VG_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
+      break;
+
+   case VKI_SYS_SOCKET:
+      /* int socket(int domain, int type, int protocol); */
+      PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
+      break;
+
+   case VKI_SYS_BIND:
+      /* int bind(int sockfd, struct sockaddr *my_addr, 
+                  int addrlen); */
+      PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
+      VG_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+               
+   case VKI_SYS_LISTEN:
+      /* int listen(int s, int backlog); */
+      PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
+      break;
+
+   case VKI_SYS_ACCEPT: {
+      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+      PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
+      VG_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+   }
+
+   case VKI_SYS_SENDTO:
+      /* int sendto(int s, const void *msg, int len, 
+                    unsigned int flags, 
+                    const struct sockaddr *to, int tolen); */
+      PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
+      VG_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2, 
+                                   ARG2_3, ARG2_4, ARG2_5 );
+      break;
+
+   case VKI_SYS_SEND:
+      /* int send(int s, const void *msg, size_t len, int flags); */
+      PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
+      VG_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_RECVFROM:
+      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
+         struct sockaddr *from, int *fromlen); */
+      PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
+      VG_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2, 
+                                     ARG2_3, ARG2_4, ARG2_5 );
+      break;
+   
+   case VKI_SYS_RECV:
+      /* int recv(int s, void *buf, int len, unsigned int flags); */
+      /* man 2 recv says:
+         The  recv call is normally used only on a connected socket
+         (see connect(2)) and is identical to recvfrom with a  NULL
+         from parameter.
+      */
+      PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
+      VG_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_CONNECT:
+      /* int connect(int sockfd, 
+                     struct sockaddr *serv_addr, int addrlen ); */
+      PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
+      VG_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_SETSOCKOPT:
+      /* int setsockopt(int s, int level, int optname, 
+                        const void *optval, int optlen); */
+      PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
+      VG_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 
+                                       ARG2_3, ARG2_4 );
+      break;
+
+   case VKI_SYS_GETSOCKOPT:
+      /* int getsockopt(int s, int level, int optname, 
+                        void *optval, socklen_t *optlen); */
+      PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
+      VG_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, 
+                                       ARG2_3, ARG2_4 );
+      break;
+
+   case VKI_SYS_GETSOCKNAME:
+      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
+      PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
+      VG_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_GETPEERNAME:
+      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
+      PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
+      VG_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_SHUTDOWN:
+      /* int shutdown(int s, int how); */
+      PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
+      break;
+
+   case VKI_SYS_SENDMSG: {
+      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
+
+      /* this causes warnings, and I don't get why. glibc bug?
+       * (after all it's glibc providing the arguments array)
+       PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
+      */
+      VG_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
+      break;
+   }
+      
+   case VKI_SYS_RECVMSG: {
+      /* int recvmsg(int s, struct msghdr *msg, int flags); */
+
+      /* this causes warnings, and I don't get why. glibc bug?
+       * (after all it's glibc providing the arguments array)
+       PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
+      */
+      VG_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
+      break;
+   }
+
+   default:
+      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
+      SET_STATUS_Failure( VKI_EINVAL );
+      break;
+   }
+#  undef ARG2_0
+#  undef ARG2_1
+#  undef ARG2_2
+#  undef ARG2_3
+#  undef ARG2_4
+#  undef ARG2_5
+}
+
+POST(sys_socketcall)
+{
+#  define ARG2_0  (((UWord*)ARG2)[0])
+#  define ARG2_1  (((UWord*)ARG2)[1])
+#  define ARG2_2  (((UWord*)ARG2)[2])
+#  define ARG2_3  (((UWord*)ARG2)[3])
+#  define ARG2_4  (((UWord*)ARG2)[4])
+#  define ARG2_5  (((UWord*)ARG2)[5])
+
+   SysRes r;
+   vg_assert(SUCCESS);
+   switch (ARG1 /* request */) {
+
+   case VKI_SYS_SOCKETPAIR:
+      r = VG_(generic_POST_sys_socketpair)( 
+             tid, VG_(mk_SysRes_Success)(RES), 
+             ARG2_0, ARG2_1, ARG2_2, ARG2_3 
+          );
+      SET_STATUS_from_SysRes(r);
+      break;
+
+   case VKI_SYS_SOCKET:
+      r = VG_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
+      SET_STATUS_from_SysRes(r);
+      break;
+
+   case VKI_SYS_BIND:
+      /* int bind(int sockfd, struct sockaddr *my_addr, 
+			int addrlen); */
+      break;
+               
+   case VKI_SYS_LISTEN:
+      /* int listen(int s, int backlog); */
+      break;
+
+   case VKI_SYS_ACCEPT:
+      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
+     r = VG_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES), 
+                                            ARG2_0, ARG2_1, ARG2_2 );
+     SET_STATUS_from_SysRes(r);
+     break;
+
+   case VKI_SYS_SENDTO:
+      break;
+
+   case VKI_SYS_SEND:
+      break;
+
+   case VKI_SYS_RECVFROM:
+      VG_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
+                                           ARG2_0, ARG2_1, ARG2_2,
+                                           ARG2_3, ARG2_4, ARG2_5 );
+      break;
+
+   case VKI_SYS_RECV:
+      VG_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_CONNECT:
+      break;
+
+   case VKI_SYS_SETSOCKOPT:
+      break;
+
+   case VKI_SYS_GETSOCKOPT:
+      VG_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
+                                             ARG2_0, ARG2_1, 
+                                             ARG2_2, ARG2_3, ARG2_4 );
+      break;
+
+   case VKI_SYS_GETSOCKNAME:
+      VG_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
+                                              ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_GETPEERNAME:
+      VG_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES), 
+                                              ARG2_0, ARG2_1, ARG2_2 );
+      break;
+
+   case VKI_SYS_SHUTDOWN:
+      break;
+
+   case VKI_SYS_SENDMSG:
+      break;
+
+   case VKI_SYS_RECVMSG:
+     VG_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
+     break;
+
+   default:
+      VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
+      VG_(core_panic)("... bye!\n");
+      break; /*NOTREACHED*/
+   }
+#  undef ARG2_0
+#  undef ARG2_1
+#  undef ARG2_2
+#  undef ARG2_3
+#  undef ARG2_4
+#  undef ARG2_5
+}
+
+//zz // jrs 20050207: this is from the svn branch
+//zz //PRE(sys_sigaction, Special)
+//zz //{
+//zz //   PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz //   PRE_REG_READ3(int, "sigaction",
+//zz //                 int, signum, const struct old_sigaction *, act,
+//zz //                 struct old_sigaction *, oldact)
+//zz //   if (ARG2 != 0)
+//zz //      PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
+//zz //   if (ARG3 != 0)
+//zz //      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
+//zz //
+//zz //   VG_(do_sys_sigaction)(tid);
+//zz //}
+//zz 
+//zz /* Convert from non-RT to RT sigset_t's */
+//zz static void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
+//zz {
+//zz    VG_(sigemptyset)(set);
+//zz    set->sig[0] = *oldset;
+//zz }
+//zz PRE(sys_sigaction, Special)
+//zz {
+//zz    struct vki_sigaction new, old;
+//zz    struct vki_sigaction *newp, *oldp;
+//zz 
+//zz    PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
+//zz    PRE_REG_READ3(int, "sigaction",
+//zz                  int, signum, const struct old_sigaction *, act,
+//zz                  struct old_sigaction *, oldact);
+//zz 
+//zz    newp = oldp = NULL;
+//zz 
+//zz    if (ARG2 != 0)
+//zz       PRE_MEM_READ( "sigaction(act)", ARG2, sizeof(struct vki_old_sigaction));
+//zz 
+//zz    if (ARG3 != 0) {
+//zz       PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
+//zz       oldp = &old;
+//zz    }
+//zz 
+//zz    //jrs 20050207: what?!  how can this make any sense?
+//zz    //if (VG_(is_kerror)(SYSRES))
+//zz    //   return;
+//zz 
+//zz    if (ARG2 != 0) {
+//zz       struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
+//zz 
+//zz       new.ksa_handler = oldnew->ksa_handler;
+//zz       new.sa_flags = oldnew->sa_flags;
+//zz       new.sa_restorer = oldnew->sa_restorer;
+//zz       convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
+//zz       newp = &new;
+//zz    }
+//zz 
+//zz    SET_STATUS_( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
+//zz 
+//zz    if (ARG3 != 0 && RES == 0) {
+//zz       struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
+//zz 
+//zz       oldold->ksa_handler = oldp->ksa_handler;
+//zz       oldold->sa_flags = oldp->sa_flags;
+//zz       oldold->sa_restorer = oldp->sa_restorer;
+//zz       oldold->sa_mask = oldp->sa_mask.sig[0];
+//zz    }
+//zz }
+//zz 
+//zz POST(sys_sigaction)
+//zz {
+//zz    if (RES == 0 && ARG3 != 0)
+//zz       POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
+//zz }
+//zz 
+//zz #undef PRE
+//zz #undef POST
 
 /* ---------------------------------------------------------------------
    The x86/Linux syscall table
    ------------------------------------------------------------------ */
 
-// Macros for adding x86/Linux-specific wrappers to the syscall table.
-#define PLAX_(const, name)    SYS_WRAPPER_ENTRY_X_(x86_linux, const, name) 
-#define PLAXY(const, name)    SYS_WRAPPER_ENTRY_XY(x86_linux, const, name) 
+/* Add a Linux-specific, arch-independent wrapper to a syscall
+   table. */
+#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(x86_linux, sysno, name) 
+#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(x86_linux, sysno, name)
+
 
 // This table maps from __NR_xxx syscall numbers (from
 // linux/include/asm-i386/unistd.h) to the appropriate PRE/POST sys_foo()
@@ -1505,8 +1912,8 @@
 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
 // (unknown).
 
-const struct SyscallTableEntry VGA_(syscall_table)[] = {
-   //   (restart_syscall)                             // 0
+const SyscallTableEntry VGP_(syscall_table)[] = {
+//zz    //   (restart_syscall)                             // 0
    GENX_(__NR_exit,              sys_exit),           // 1
    GENX_(__NR_fork,              sys_fork),           // 2
    GENXY(__NR_read,              sys_read),           // 3
@@ -1525,9 +1932,9 @@
    GENX_(__NR_mknod,             sys_mknod),          // 14
 
    GENX_(__NR_chmod,             sys_chmod),          // 15
-   //   (__NR_lchown,            sys_lchown16),       // 16 ## P
+//zz    //   (__NR_lchown,            sys_lchown16),       // 16 ## P
    GENX_(__NR_break,             sys_ni_syscall),     // 17
-   //   (__NR_oldstat,           sys_stat),           // 18 (obsolete)
+//zz    //   (__NR_oldstat,           sys_stat),           // 18 (obsolete)
    GENX_(__NR_lseek,             sys_lseek),          // 19
 
    GENX_(__NR_getpid,            sys_getpid),         // 20
@@ -1535,324 +1942,324 @@
    LINX_(__NR_umount,            sys_oldumount),      // 22
    GENX_(__NR_setuid,            sys_setuid16),       // 23 ## P
    GENX_(__NR_getuid,            sys_getuid16),       // 24 ## P
-
-   //   (__NR_stime,             sys_stime),          // 25 * (SVr4,SVID,X/OPEN)
-   PLAXY(__NR_ptrace,            sys_ptrace),         // 26
+//zz 
+//zz    //   (__NR_stime,             sys_stime),          // 25 * (SVr4,SVID,X/OPEN)
+//zz    PLAXY(__NR_ptrace,            sys_ptrace),         // 26
    GENX_(__NR_alarm,             sys_alarm),          // 27
-   //   (__NR_oldfstat,          sys_fstat),          // 28 * L -- obsolete
+//zz    //   (__NR_oldfstat,          sys_fstat),          // 28 * L -- obsolete
    GENX_(__NR_pause,             sys_pause),          // 29
-
-   GENX_(__NR_utime,             sys_utime),          // 30
+//zz 
+//zz    GENX_(__NR_utime,             sys_utime),          // 30
    GENX_(__NR_stty,              sys_ni_syscall),     // 31
    GENX_(__NR_gtty,              sys_ni_syscall),     // 32
    GENX_(__NR_access,            sys_access),         // 33
-   GENX_(__NR_nice,              sys_nice),           // 34
-
+//zz    GENX_(__NR_nice,              sys_nice),           // 34
+//zz 
    GENX_(__NR_ftime,             sys_ni_syscall),     // 35
-   GENX_(__NR_sync,              sys_sync),           // 36
+//zz    GENX_(__NR_sync,              sys_sync),           // 36
    GENX_(__NR_kill,              sys_kill),           // 37
    GENX_(__NR_rename,            sys_rename),         // 38
    GENX_(__NR_mkdir,             sys_mkdir),          // 39
-
-   GENX_(__NR_rmdir,             sys_rmdir),          // 40
+//zz 
+//zz    GENX_(__NR_rmdir,             sys_rmdir),          // 40
    GENXY(__NR_dup,               sys_dup),            // 41
    GENXY(__NR_pipe,              sys_pipe),           // 42
-   GENXY(__NR_times,             sys_times),          // 43
+//zz    GENXY(__NR_times,             sys_times),          // 43
    GENX_(__NR_prof,              sys_ni_syscall),     // 44
-
+//zz 
    GENX_(__NR_brk,               sys_brk),            // 45
-   GENX_(__NR_setgid,            sys_setgid16),       // 46
-   GENX_(__NR_getgid,            sys_getgid16),       // 47
-   //   (__NR_signal,            sys_signal),         // 48 */* (ANSI C)
+//zz    GENX_(__NR_setgid,            sys_setgid16),       // 46
+//zz    GENX_(__NR_getgid,            sys_getgid16),       // 47
+//zz    //   (__NR_signal,            sys_signal),         // 48 */* (ANSI C)
    GENX_(__NR_geteuid,           sys_geteuid16),      // 49
-
-   GENX_(__NR_getegid,           sys_getegid16),      // 50
-   GENX_(__NR_acct,              sys_acct),           // 51
-   LINX_(__NR_umount2,           sys_umount),         // 52
+//zz 
+//zz    GENX_(__NR_getegid,           sys_getegid16),      // 50
+//zz    GENX_(__NR_acct,              sys_acct),           // 51
+//zz    LINX_(__NR_umount2,           sys_umount),         // 52
    GENX_(__NR_lock,              sys_ni_syscall),     // 53
    GENXY(__NR_ioctl,             sys_ioctl),          // 54
-
-   GENXY(__NR_fcntl,             sys_fcntl),          // 55
+//zz 
+//zz    GENXY(__NR_fcntl,             sys_fcntl),          // 55
    GENX_(__NR_mpx,               sys_ni_syscall),     // 56
-   GENX_(__NR_setpgid,           sys_setpgid),        // 57
+//zz    GENX_(__NR_setpgid,           sys_setpgid),        // 57
    GENX_(__NR_ulimit,            sys_ni_syscall),     // 58
-   //   (__NR_oldolduname,       sys_olduname),       // 59 Linux -- obsolete
-
-   GENX_(__NR_umask,             sys_umask),          // 60
-   GENX_(__NR_chroot,            sys_chroot),         // 61
-   //   (__NR_ustat,             sys_ustat)           // 62 SVr4 -- deprecated
+//zz    //   (__NR_oldolduname,       sys_olduname),       // 59 Linux -- obsolete
+//zz 
+//zz    GENX_(__NR_umask,             sys_umask),          // 60
+//zz    GENX_(__NR_chroot,            sys_chroot),         // 61
+//zz    //   (__NR_ustat,             sys_ustat)           // 62 SVr4 -- deprecated
    GENXY(__NR_dup2,              sys_dup2),           // 63
    GENX_(__NR_getppid,           sys_getppid),        // 64
-
-   GENX_(__NR_getpgrp,           sys_getpgrp),        // 65
-   GENX_(__NR_setsid,            sys_setsid),         // 66
-   PLAXY(__NR_sigaction,         sys_sigaction),      // 67
-   //   (__NR_sgetmask,          sys_sgetmask),       // 68 */* (ANSI C)
-   //   (__NR_ssetmask,          sys_ssetmask),       // 69 */* (ANSI C)
-
-   GENX_(__NR_setreuid,          sys_setreuid16),     // 70
-   GENX_(__NR_setregid,          sys_setregid16),     // 71
-   GENX_(__NR_sigsuspend,        sys_sigsuspend),     // 72
-   GENXY(__NR_sigpending,        sys_sigpending),     // 73
-   //   (__NR_sethostname,       sys_sethostname),    // 74 */*
-
+//zz 
+//zz    GENX_(__NR_getpgrp,           sys_getpgrp),        // 65
+//zz    GENX_(__NR_setsid,            sys_setsid),         // 66
+//zz    PLAXY(__NR_sigaction,         sys_sigaction),      // 67
+//zz    //   (__NR_sgetmask,          sys_sgetmask),       // 68 */* (ANSI C)
+//zz    //   (__NR_ssetmask,          sys_ssetmask),       // 69 */* (ANSI C)
+//zz 
+//zz    GENX_(__NR_setreuid,          sys_setreuid16),     // 70
+//zz    GENX_(__NR_setregid,          sys_setregid16),     // 71
+//zz    GENX_(__NR_sigsuspend,        sys_sigsuspend),     // 72
+//zz    GENXY(__NR_sigpending,        sys_sigpending),     // 73
+//zz    //   (__NR_sethostname,       sys_sethostname),    // 74 */*
+//zz 
    GENX_(__NR_setrlimit,         sys_setrlimit),      // 75
-   GENXY(__NR_getrlimit,         sys_old_getrlimit),  // 76
-   GENXY(__NR_getrusage,         sys_getrusage),      // 77
+//zz    GENXY(__NR_getrlimit,         sys_old_getrlimit),  // 76
+//zz    GENXY(__NR_getrusage,         sys_getrusage),      // 77
    GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 78
-   GENX_(__NR_settimeofday,      sys_settimeofday),   // 79
-
-   GENXY(__NR_getgroups,         sys_getgroups16),    // 80
-   GENX_(__NR_setgroups,         sys_setgroups16),    // 81
-   PLAX_(__NR_select,            old_select),         // 82
-   GENX_(__NR_symlink,           sys_symlink),        // 83
-   //   (__NR_oldlstat,          sys_lstat),          // 84 -- obsolete
-
+//zz    GENX_(__NR_settimeofday,      sys_settimeofday),   // 79
+//zz 
+//zz    GENXY(__NR_getgroups,         sys_getgroups16),    // 80
+//zz    GENX_(__NR_setgroups,         sys_setgroups16),    // 81
+//zz    PLAX_(__NR_select,            old_select),         // 82
+//zz    GENX_(__NR_symlink,           sys_symlink),        // 83
+//zz    //   (__NR_oldlstat,          sys_lstat),          // 84 -- obsolete
+//zz 
    GENX_(__NR_readlink,          sys_readlink),       // 85
-   //   (__NR_uselib,            sys_uselib),         // 86 */Linux
-   //   (__NR_swapon,            sys_swapon),         // 87 */Linux
-   //   (__NR_reboot,            sys_reboot),         // 88 */Linux
-   //   (__NR_readdir,           old_readdir),        // 89 -- superseded
-
-   GENX_(__NR_mmap,              old_mmap),           // 90
+//zz    //   (__NR_uselib,            sys_uselib),         // 86 */Linux
+//zz    //   (__NR_swapon,            sys_swapon),         // 87 */Linux
+//zz    //   (__NR_reboot,            sys_reboot),         // 88 */Linux
+//zz    //   (__NR_readdir,           old_readdir),        // 89 -- superseded
+//zz 
+   PLAX_(__NR_mmap,              old_mmap),           // 90
    GENXY(__NR_munmap,            sys_munmap),         // 91
-   GENX_(__NR_truncate,          sys_truncate),       // 92
-   GENX_(__NR_ftruncate,         sys_ftruncate),      // 93
-   GENX_(__NR_fchmod,            sys_fchmod),         // 94
-
-   GENX_(__NR_fchown,            sys_fchown16),       // 95
-   GENX_(__NR_getpriority,       sys_getpriority),    // 96
-   GENX_(__NR_setpriority,       sys_setpriority),    // 97
+//zz    GENX_(__NR_truncate,          sys_truncate),       // 92
+//zz    GENX_(__NR_ftruncate,         sys_ftruncate),      // 93
+//zz    GENX_(__NR_fchmod,            sys_fchmod),         // 94
+//zz 
+//zz    GENX_(__NR_fchown,            sys_fchown16),       // 95
+//zz    GENX_(__NR_getpriority,       sys_getpriority),    // 96
+//zz    GENX_(__NR_setpriority,       sys_setpriority),    // 97
    GENX_(__NR_profil,            sys_ni_syscall),     // 98
-   GENXY(__NR_statfs,            sys_statfs),         // 99
-
-   GENXY(__NR_fstatfs,           sys_fstatfs),        // 100
-   LINX_(__NR_ioperm,            sys_ioperm),         // 101
-   GENXY(__NR_socketcall,        sys_socketcall),     // 102
-   LINXY(__NR_syslog,            sys_syslog),         // 103
-   GENXY(__NR_setitimer,         sys_setitimer),      // 104
-
-   GENXY(__NR_getitimer,         sys_getitimer),      // 105
-   GENXY(__NR_stat,              sys_newstat),        // 106
-   GENXY(__NR_lstat,             sys_newlstat),       // 107
-   GENXY(__NR_fstat,             sys_newfstat),       // 108
-   //   (__NR_olduname,          sys_uname),          // 109 -- obsolete
-
-   GENX_(__NR_iopl,              sys_iopl),           // 110
-   LINX_(__NR_vhangup,           sys_vhangup),        // 111
+//zz    GENXY(__NR_statfs,            sys_statfs),         // 99
+//zz 
+//zz    GENXY(__NR_fstatfs,           sys_fstatfs),        // 100
+//zz    LINX_(__NR_ioperm,            sys_ioperm),         // 101
+   PLAXY(__NR_socketcall,        sys_socketcall),     // 102 x86/Linux-only
+//zz    LINXY(__NR_syslog,            sys_syslog),         // 103
+//zz    GENXY(__NR_setitimer,         sys_setitimer),      // 104
+//zz 
+//zz    GENXY(__NR_getitimer,         sys_getitimer),      // 105
+//zz    GENXY(__NR_stat,              sys_newstat),        // 106
+//zz    GENXY(__NR_lstat,             sys_newlstat),       // 107
+//zz    GENXY(__NR_fstat,             sys_newfstat),       // 108
+//zz    //   (__NR_olduname,          sys_uname),          // 109 -- obsolete
+//zz 
+//zz    GENX_(__NR_iopl,              sys_iopl),           // 110
+//zz    LINX_(__NR_vhangup,           sys_vhangup),        // 111
    GENX_(__NR_idle,              sys_ni_syscall),     // 112
-   //   (__NR_vm86old,           sys_vm86old),        // 113 x86/Linux-only
+//zz    //   (__NR_vm86old,           sys_vm86old),        // 113 x86/Linux-only
    GENXY(__NR_wait4,             sys_wait4),          // 114
-
-   //   (__NR_swapoff,           sys_swapoff),        // 115 */Linux 
-   LINXY(__NR_sysinfo,           sys_sysinfo),        // 116
+//zz 
+//zz    //   (__NR_swapoff,           sys_swapoff),        // 115 */Linux 
+//zz    LINXY(__NR_sysinfo,           sys_sysinfo),        // 116
    PLAXY(__NR_ipc,               sys_ipc),            // 117
-   GENX_(__NR_fsync,             sys_fsync),          // 118
+//zz    GENX_(__NR_fsync,             sys_fsync),          // 118
    PLAX_(__NR_sigreturn,         sys_sigreturn),      // 119 ?/Linux
 
    PLAX_(__NR_clone,             sys_clone),          // 120
-   //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
+//zz    //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
    GENXY(__NR_uname,             sys_newuname),       // 122
    PLAX_(__NR_modify_ldt,        sys_modify_ldt),     // 123
-   LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
-
+//zz    LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
+//zz 
    GENXY(__NR_mprotect,          sys_mprotect),       // 125
    GENXY(__NR_sigprocmask,       sys_sigprocmask),    // 126
-   // Nb: create_module() was removed 2.4-->2.6
+//zz    // Nb: create_module() was removed 2.4-->2.6
    GENX_(__NR_create_module,     sys_ni_syscall),     // 127
-   GENX_(__NR_init_module,       sys_init_module),    // 128
-   //   (__NR_delete_module,     sys_delete_module),  // 129 (*/Linux)?
-
-   // Nb: get_kernel_syms() was removed 2.4-->2.6
+//zz    GENX_(__NR_init_module,       sys_init_module),    // 128
+//zz    //   (__NR_delete_module,     sys_delete_module),  // 129 (*/Linux)?
+//zz 
+//zz    // Nb: get_kernel_syms() was removed 2.4-->2.6
    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),     // 130
-   GENX_(__NR_quotactl,          sys_quotactl),       // 131
-   GENX_(__NR_getpgid,           sys_getpgid),        // 132
-   GENX_(__NR_fchdir,            sys_fchdir),         // 133
-   //   (__NR_bdflush,           sys_bdflush),        // 134 */Linux
-
-   //   (__NR_sysfs,             sys_sysfs),          // 135 SVr4
-   LINX_(__NR_personality,       sys_personality),    // 136
+//zz    GENX_(__NR_quotactl,          sys_quotactl),       // 131
+//zz    GENX_(__NR_getpgid,           sys_getpgid),        // 132
+//zz    GENX_(__NR_fchdir,            sys_fchdir),         // 133
+//zz    //   (__NR_bdflush,           sys_bdflush),        // 134 */Linux
+//zz 
+//zz    //   (__NR_sysfs,             sys_sysfs),          // 135 SVr4
+//zz    LINX_(__NR_personality,       sys_personality),    // 136
    GENX_(__NR_afs_syscall,       sys_ni_syscall),     // 137
-   LINX_(__NR_setfsuid,          sys_setfsuid16),     // 138
-   LINX_(__NR_setfsgid,          sys_setfsgid16),     // 139
-
+//zz    LINX_(__NR_setfsuid,          sys_setfsuid16),     // 138
+//zz    LINX_(__NR_setfsgid,          sys_setfsgid16),     // 139
+//zz 
    LINXY(__NR__llseek,           sys_llseek),         // 140
-   GENXY(__NR_getdents,          sys_getdents),       // 141
+//zz    GENXY(__NR_getdents,          sys_getdents),       // 141
    GENX_(__NR__newselect,        sys_select),         // 142
-   GENX_(__NR_flock,             sys_flock),          // 143
-   GENX_(__NR_msync,             sys_msync),          // 144
-
+//zz    GENX_(__NR_flock,             sys_flock),          // 143
+//zz    GENX_(__NR_msync,             sys_msync),          // 144
+//zz 
    GENXY(__NR_readv,             sys_readv),          // 145
    GENX_(__NR_writev,            sys_writev),         // 146
-   GENX_(__NR_getsid,            sys_getsid),         // 147
-   GENX_(__NR_fdatasync,         sys_fdatasync),      // 148
+//zz    GENX_(__NR_getsid,            sys_getsid),         // 147
+//zz    GENX_(__NR_fdatasync,         sys_fdatasync),      // 148
    LINXY(__NR__sysctl,           sys_sysctl),         // 149
-
-   GENX_(__NR_mlock,             sys_mlock),          // 150
-   GENX_(__NR_munlock,           sys_munlock),        // 151
-   GENX_(__NR_mlockall,          sys_mlockall),       // 152
-   GENX_(__NR_munlockall,        sys_munlockall),     // 153
-   GENXY(__NR_sched_setparam,    sys_sched_setparam), // 154
-
-   GENXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
-   GENX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
-   GENX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
-   GENX_(__NR_sched_yield,            sys_sched_yield),           // 158
-   GENX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
-
-   GENX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
-   //   (__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
+//zz 
+//zz    GENX_(__NR_mlock,             sys_mlock),          // 150
+//zz    GENX_(__NR_munlock,           sys_munlock),        // 151
+//zz    GENX_(__NR_mlockall,          sys_mlockall),       // 152
+//zz    GENX_(__NR_munlockall,        sys_munlockall),     // 153
+//zz    GENXY(__NR_sched_setparam,    sys_sched_setparam), // 154
+//zz 
+//zz    GENXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
+//zz    GENX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
+//zz    GENX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
+//zz    GENX_(__NR_sched_yield,            sys_sched_yield),           // 158
+//zz    GENX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
+//zz 
+//zz    GENX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
+//zz    //   (__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
    GENXY(__NR_nanosleep,         sys_nanosleep),      // 162
    GENX_(__NR_mremap,            sys_mremap),         // 163
-   LINX_(__NR_setresuid,         sys_setresuid16),    // 164
-
-   LINXY(__NR_getresuid,         sys_getresuid16),    // 165
-   //   (__NR_vm86,              sys_vm86),           // 166 x86/Linux-only
+//zz    LINX_(__NR_setresuid,         sys_setresuid16),    // 164
+//zz 
+//zz    LINXY(__NR_getresuid,         sys_getresuid16),    // 165
+//zz    //   (__NR_vm86,              sys_vm86),           // 166 x86/Linux-only
    GENX_(__NR_query_module,      sys_ni_syscall),     // 167
    GENXY(__NR_poll,              sys_poll),           // 168
-   //   (__NR_nfsservctl,        sys_nfsservctl),     // 169 */Linux
-
-   LINX_(__NR_setresgid,         sys_setresgid16),    // 170
-   LINXY(__NR_getresgid,         sys_getresgid16),    // 171
-   LINX_(__NR_prctl,             sys_prctl),          // 172
+//zz    //   (__NR_nfsservctl,        sys_nfsservctl),     // 169 */Linux
+//zz 
+//zz    LINX_(__NR_setresgid,         sys_setresgid16),    // 170
+//zz    LINXY(__NR_getresgid,         sys_getresgid16),    // 171
+//zz    LINX_(__NR_prctl,             sys_prctl),          // 172
    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 173 x86/Linux only?
    GENXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 174
 
    GENXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 175
-   GENXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 176
+//zz    GENXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 176
    GENXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 177
-   GENXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 178
+//zz    GENXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 178
    GENX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 179
-
-   GENXY(__NR_pread64,           sys_pread64),        // 180
-   GENX_(__NR_pwrite64,          sys_pwrite64),       // 181
-   GENX_(__NR_chown,             sys_chown16),        // 182
+//zz 
+//zz    GENXY(__NR_pread64,           sys_pread64),        // 180
+//zz    GENX_(__NR_pwrite64,          sys_pwrite64),       // 181
+//zz    GENX_(__NR_chown,             sys_chown16),        // 182
    GENXY(__NR_getcwd,            sys_getcwd),         // 183
-   GENXY(__NR_capget,            sys_capget),         // 184
-
-   GENX_(__NR_capset,            sys_capset),         // 185
+//zz    GENXY(__NR_capget,            sys_capget),         // 184
+//zz 
+//zz    GENX_(__NR_capset,            sys_capset),         // 185
    GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 186
-   LINXY(__NR_sendfile,          sys_sendfile),       // 187
-   GENXY(__NR_getpmsg,           sys_getpmsg),        // 188
-   GENX_(__NR_putpmsg,           sys_putpmsg),        // 189
+//zz    LINXY(__NR_sendfile,          sys_sendfile),       // 187
+//zz    GENXY(__NR_getpmsg,           sys_getpmsg),        // 188
+//zz    GENX_(__NR_putpmsg,           sys_putpmsg),        // 189
 
    // Nb: we treat vfork as fork
    GENX_(__NR_vfork,             sys_fork),           // 190
    GENXY(__NR_ugetrlimit,        sys_getrlimit),      // 191
    GENXY(__NR_mmap2,             sys_mmap2),          // 192
-   GENX_(__NR_truncate64,        sys_truncate64),     // 193
-   GENX_(__NR_ftruncate64,       sys_ftruncate64),    // 194
-   
-   GENXY(__NR_stat64,            sys_stat64),         // 195
-   GENXY(__NR_lstat64,           sys_lstat64),        // 196
-   GENXY(__NR_fstat64,           sys_fstat64),        // 197
-   GENX_(__NR_lchown32,          sys_lchown),         // 198
+//zz    GENX_(__NR_truncate64,        sys_truncate64),     // 193
+//zz    GENX_(__NR_ftruncate64,       sys_ftruncate64),    // 194
+//zz    
+   PLAXY(__NR_stat64,            sys_stat64),         // 195
+   PLAXY(__NR_lstat64,           sys_lstat64),        // 196
+   PLAXY(__NR_fstat64,           sys_fstat64),        // 197
+//zz    GENX_(__NR_lchown32,          sys_lchown),         // 198
    GENX_(__NR_getuid32,          sys_getuid),         // 199
-
-   GENX_(__NR_getgid32,          sys_getgid),         // 200
+//zz 
+//zz    GENX_(__NR_getgid32,          sys_getgid),         // 200
    GENX_(__NR_geteuid32,         sys_geteuid),        // 201
-   GENX_(__NR_getegid32,         sys_getegid),        // 202
-   GENX_(__NR_setreuid32,        sys_setreuid),       // 203
-   GENX_(__NR_setregid32,        sys_setregid),       // 204
-
-   GENXY(__NR_getgroups32,       sys_getgroups),      // 205
-   GENX_(__NR_setgroups32,       sys_setgroups),      // 206
-   GENX_(__NR_fchown32,          sys_fchown),         // 207
-   LINX_(__NR_setresuid32,       sys_setresuid),      // 208
-   LINXY(__NR_getresuid32,       sys_getresuid),      // 209
-
-   LINX_(__NR_setresgid32,       sys_setresgid),      // 210
-   LINXY(__NR_getresgid32,       sys_getresgid),      // 211
-   GENX_(__NR_chown32,           sys_chown),          // 212
-   GENX_(__NR_setuid32,          sys_setuid),         // 213
-   GENX_(__NR_setgid32,          sys_setgid),         // 214
-
-   LINX_(__NR_setfsuid32,        sys_setfsuid),       // 215
-   LINX_(__NR_setfsgid32,        sys_setfsgid),       // 216
-   //   (__NR_pivot_root,        sys_pivot_root),     // 217 */Linux
-   GENXY(__NR_mincore,           sys_mincore),        // 218
+//zz    GENX_(__NR_getegid32,         sys_getegid),        // 202
+//zz    GENX_(__NR_setreuid32,        sys_setreuid),       // 203
+//zz    GENX_(__NR_setregid32,        sys_setregid),       // 204
+//zz 
+//zz    GENXY(__NR_getgroups32,       sys_getgroups),      // 205
+//zz    GENX_(__NR_setgroups32,       sys_setgroups),      // 206
+//zz    GENX_(__NR_fchown32,          sys_fchown),         // 207
+//zz    LINX_(__NR_setresuid32,       sys_setresuid),      // 208
+//zz    LINXY(__NR_getresuid32,       sys_getresuid),      // 209
+//zz 
+//zz    LINX_(__NR_setresgid32,       sys_setresgid),      // 210
+//zz    LINXY(__NR_getresgid32,       sys_getresgid),      // 211
+//zz    GENX_(__NR_chown32,           sys_chown),          // 212
+//zz    GENX_(__NR_setuid32,          sys_setuid),         // 213
+//zz    GENX_(__NR_setgid32,          sys_setgid),         // 214
+//zz 
+//zz    LINX_(__NR_setfsuid32,        sys_setfsuid),       // 215
+//zz    LINX_(__NR_setfsgid32,        sys_setfsgid),       // 216
+//zz    //   (__NR_pivot_root,        sys_pivot_root),     // 217 */Linux
+//zz    GENXY(__NR_mincore,           sys_mincore),        // 218
    GENX_(__NR_madvise,           sys_madvise),        // 219
 
    GENXY(__NR_getdents64,        sys_getdents64),     // 220
    GENXY(__NR_fcntl64,           sys_fcntl64),        // 221
    GENX_(222,                    sys_ni_syscall),     // 222
    GENX_(223,                    sys_ni_syscall),     // 223
-   LINX_(__NR_gettid,            sys_gettid),         // 224
-
-   //   (__NR_readahead,         sys_readahead),      // 225 */(Linux?)
-   GENX_(__NR_setxattr,          sys_setxattr),       // 226
-   GENX_(__NR_lsetxattr,         sys_lsetxattr),      // 227
-   GENX_(__NR_fsetxattr,         sys_fsetxattr),      // 228
+//zz    LINX_(__NR_gettid,            sys_gettid),         // 224
+//zz 
+//zz    //   (__NR_readahead,         sys_readahead),      // 225 */(Linux?)
+//zz    GENX_(__NR_setxattr,          sys_setxattr),       // 226
+//zz    GENX_(__NR_lsetxattr,         sys_lsetxattr),      // 227
+//zz    GENX_(__NR_fsetxattr,         sys_fsetxattr),      // 228
    GENXY(__NR_getxattr,          sys_getxattr),       // 229
-
-   GENXY(__NR_lgetxattr,         sys_lgetxattr),      // 230
-   GENXY(__NR_fgetxattr,         sys_fgetxattr),      // 231
-   GENXY(__NR_listxattr,         sys_listxattr),      // 232
-   GENXY(__NR_llistxattr,        sys_llistxattr),     // 233
-   GENXY(__NR_flistxattr,        sys_flistxattr),     // 234
-
-   GENX_(__NR_removexattr,       sys_removexattr),    // 235
-   GENX_(__NR_lremovexattr,      sys_lremovexattr),   // 236
-   GENX_(__NR_fremovexattr,      sys_fremovexattr),   // 237
-   LINX_(__NR_tkill,             sys_tkill),          // 238 */Linux
-   LINXY(__NR_sendfile64,        sys_sendfile64),     // 239
-
-   LINXY(__NR_futex,             sys_futex),             // 240
-   GENX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
-   GENXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
-   PLAX_(__NR_set_thread_area,   sys_set_thread_area),   // 243
-   PLAX_(__NR_get_thread_area,   sys_get_thread_area),   // 244
-
-   LINX_(__NR_io_setup,          sys_io_setup),       // 245
-   LINX_(__NR_io_destroy,        sys_io_destroy),     // 246
-   LINXY(__NR_io_getevents,      sys_io_getevents),   // 247
-   LINX_(__NR_io_submit,         sys_io_submit),      // 248
-   LINXY(__NR_io_cancel,         sys_io_cancel),      // 249
-
-   LINX_(__NR_fadvise64,         sys_fadvise64),      // 250 */(Linux?)
+//zz 
+//zz    GENXY(__NR_lgetxattr,         sys_lgetxattr),      // 230
+//zz    GENXY(__NR_fgetxattr,         sys_fgetxattr),      // 231
+//zz    GENXY(__NR_listxattr,         sys_listxattr),      // 232
+//zz    GENXY(__NR_llistxattr,        sys_llistxattr),     // 233
+//zz    GENXY(__NR_flistxattr,        sys_flistxattr),     // 234
+//zz 
+//zz    GENX_(__NR_removexattr,       sys_removexattr),    // 235
+//zz    GENX_(__NR_lremovexattr,      sys_lremovexattr),   // 236
+//zz    GENX_(__NR_fremovexattr,      sys_fremovexattr),   // 237
+//zz    LINX_(__NR_tkill,             sys_tkill),          // 238 */Linux
+//zz    LINXY(__NR_sendfile64,        sys_sendfile64),     // 239
+//zz 
+//zz    LINXY(__NR_futex,             sys_futex),             // 240
+//zz    GENX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
+//zz    GENXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
+//zz    PLAX_(__NR_set_thread_area,   sys_set_thread_area),   // 243
+//zz    PLAX_(__NR_get_thread_area,   sys_get_thread_area),   // 244
+//zz 
+//zz    LINX_(__NR_io_setup,          sys_io_setup),       // 245
+//zz    LINX_(__NR_io_destroy,        sys_io_destroy),     // 246
+//zz    LINXY(__NR_io_getevents,      sys_io_getevents),   // 247
+//zz    LINX_(__NR_io_submit,         sys_io_submit),      // 248
+//zz    LINXY(__NR_io_cancel,         sys_io_cancel),      // 249
+//zz 
+//zz    LINX_(__NR_fadvise64,         sys_fadvise64),      // 250 */(Linux?)
    GENX_(251,                    sys_ni_syscall),     // 251
    LINX_(__NR_exit_group,        sys_exit_group),     // 252
-   GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 253
-   LINXY(__NR_epoll_create,      sys_epoll_create),   // 254
-
-   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 255
-   LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 256
-   //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 257 */Linux
-   GENX_(__NR_set_tid_address,   sys_set_tid_address),   // 258
-   GENXY(__NR_timer_create,      sys_timer_create),      // 259
-
-   GENXY(__NR_timer_settime,     sys_timer_settime),  // (timer_create+1)
-   GENXY(__NR_timer_gettime,     sys_timer_gettime),  // (timer_create+2)
-   GENX_(__NR_timer_getoverrun,  sys_timer_getoverrun),//(timer_create+3)
-   GENX_(__NR_timer_delete,      sys_timer_delete),   // (timer_create+4)
-   GENX_(__NR_clock_settime,     sys_clock_settime),  // (timer_create+5)
-
+//zz    GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 253
+//zz    LINXY(__NR_epoll_create,      sys_epoll_create),   // 254
+//zz 
+//zz    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 255
+//zz    LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 256
+//zz    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 257 */Linux
+//zz    GENX_(__NR_set_tid_address,   sys_set_tid_address),   // 258
+//zz    GENXY(__NR_timer_create,      sys_timer_create),      // 259
+//zz 
+//zz    GENXY(__NR_timer_settime,     sys_timer_settime),  // (timer_create+1)
+//zz    GENXY(__NR_timer_gettime,     sys_timer_gettime),  // (timer_create+2)
+//zz    GENX_(__NR_timer_getoverrun,  sys_timer_getoverrun),//(timer_create+3)
+//zz    GENX_(__NR_timer_delete,      sys_timer_delete),   // (timer_create+4)
+//zz    GENX_(__NR_clock_settime,     sys_clock_settime),  // (timer_create+5)
+//zz 
    GENXY(__NR_clock_gettime,     sys_clock_gettime),  // (timer_create+6)
-   GENXY(__NR_clock_getres,      sys_clock_getres),   // (timer_create+7)
-   //   (__NR_clock_nanosleep,   sys_clock_nanosleep),// (timer_create+8) */*
-   GENXY(__NR_statfs64,          sys_statfs64),       // 268
-   GENXY(__NR_fstatfs64,         sys_fstatfs64),      // 269
-
-   LINX_(__NR_tgkill,            sys_tgkill),         // 270 */Linux
-   GENX_(__NR_utimes,            sys_utimes),         // 271
-   LINX_(__NR_fadvise64_64,      sys_fadvise64_64),   // 272 */(Linux?)
+//zz    GENXY(__NR_clock_getres,      sys_clock_getres),   // (timer_create+7)
+//zz    //   (__NR_clock_nanosleep,   sys_clock_nanosleep),// (timer_create+8) */*
+//zz    GENXY(__NR_statfs64,          sys_statfs64),       // 268
+//zz    GENXY(__NR_fstatfs64,         sys_fstatfs64),      // 269
+//zz 
+//zz    LINX_(__NR_tgkill,            sys_tgkill),         // 270 */Linux
+//zz    GENX_(__NR_utimes,            sys_utimes),         // 271
+//zz    LINX_(__NR_fadvise64_64,      sys_fadvise64_64),   // 272 */(Linux?)
    GENX_(__NR_vserver,           sys_ni_syscall),     // 273
-   //   (__NR_mbind,             sys_mbind),          // 274 ?/?
-
-   //   (__NR_get_mempolicy,     sys_get_mempolicy),  // 275 ?/?
-   //   (__NR_set_mempolicy,     sys_set_mempolicy),  // 276 ?/?
-   GENXY(__NR_mq_open,           sys_mq_open),        // 277
-   GENX_(__NR_mq_unlink,         sys_mq_unlink),      // (mq_open+1)
-   GENX_(__NR_mq_timedsend,      sys_mq_timedsend),   // (mq_open+2)
-
-   GENXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// (mq_open+3)
-   GENX_(__NR_mq_notify,         sys_mq_notify),      // (mq_open+4)
-   GENXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // (mq_open+5)
+//zz    //   (__NR_mbind,             sys_mbind),          // 274 ?/?
+//zz 
+//zz    //   (__NR_get_mempolicy,     sys_get_mempolicy),  // 275 ?/?
+//zz    //   (__NR_set_mempolicy,     sys_set_mempolicy),  // 276 ?/?
+//zz    GENXY(__NR_mq_open,           sys_mq_open),        // 277
+//zz    GENX_(__NR_mq_unlink,         sys_mq_unlink),      // (mq_open+1)
+//zz    GENX_(__NR_mq_timedsend,      sys_mq_timedsend),   // (mq_open+2)
+//zz 
+//zz    GENXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// (mq_open+3)
+//zz    GENX_(__NR_mq_notify,         sys_mq_notify),      // (mq_open+4)
+//zz    GENXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // (mq_open+5)
    GENX_(__NR_sys_kexec_load,    sys_ni_syscall),     // 283
 };
 
-const UInt VGA_(syscall_table_size) = 
-            sizeof(VGA_(syscall_table)) / sizeof(VGA_(syscall_table)[0]);
+const UInt VGP_(syscall_table_size) = 
+            sizeof(VGP_(syscall_table)) / sizeof(VGP_(syscall_table)[0]);
 
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c
index dc06c85..962b45c 100644
--- a/coregrind/m_tooliface.c
+++ b/coregrind/m_tooliface.c
@@ -216,7 +216,7 @@
 
 void VG_(needs_syscall_wrapper)(
    void(*pre) (ThreadId, UInt),
-   void(*post)(ThreadId, UInt, Int res)
+   void(*post)(ThreadId, UInt, SysRes res)
 )
 {
    VG_(needs).syscall_wrapper = True;
diff --git a/coregrind/pub_core_libcbase.h b/coregrind/pub_core_libcbase.h
index 5c20e8b..e65c665 100644
--- a/coregrind/pub_core_libcbase.h
+++ b/coregrind/pub_core_libcbase.h
@@ -39,6 +39,74 @@
 
 #include "pub_tool_libcbase.h"
 
+/* ---------------------------------------------------------------------
+   Fundamental functions for doing syscalls on this platform.
+   ------------------------------------------------------------------ */
+
+/* Do a syscall on this platform, with 6 args, and return the result
+   in canonical format in a SysRes value. */
+
+extern SysRes VG_(do_syscall) ( UWord sysno, 
+                                UWord, UWord, UWord, 
+                                UWord, UWord, UWord );
+
+/* Macros make life easier. */
+
+#define vgPlain_do_syscall0(s)             VG_(do_syscall)((s),0,0,0,0,0,0)
+#define vgPlain_do_syscall1(s,a)           VG_(do_syscall)((s),(a),0,0,0,0,0)
+#define vgPlain_do_syscall2(s,a,b)         VG_(do_syscall)((s),(a),(b),0,0,0,0)
+#define vgPlain_do_syscall3(s,a,b,c)       VG_(do_syscall)((s),(a),(b),(c),0,0,0)
+#define vgPlain_do_syscall4(s,a,b,c,d)     VG_(do_syscall)((s),(a),(b),\
+                                                           (c),(d),0,0)
+#define vgPlain_do_syscall5(s,a,b,c,d,e)   VG_(do_syscall)((s),(a),(b),\
+                                                           (c),(d),(e),0)
+#define vgPlain_do_syscall6(s,a,b,c,d,e,f) VG_(do_syscall)((s),(a),(b),\
+                                                           (c),(d),(e),(f))
+
+
+/* Build SysRes values -- occasionally useful. */
+
+static inline SysRes VG_(mk_SysRes_Error) ( UWord err ) {
+   SysRes r = { err, True };
+   return r;
+}
+
+static inline SysRes VG_(mk_SysRes_Success) ( UWord err ) {
+   SysRes r = { err, False };
+   return r;
+}
+
+
+/* This is absolutely the wrong place for these, but I can't figure
+   out anywhere else for them to go. */
+
+/* Make a SysRes value from an %eax syscall return value on
+   x86-linux.
+
+   From:
+   http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
+   linux/i386/sysdep.h?
+   rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
+
+   Linux uses a negative return value to indicate syscall errors,
+   unlike most Unices, which use the condition codes' carry flag.
+
+   Since version 2.1 the return value of a system call might be
+   negative even if the call succeeded.  E.g., the 'lseek' system call
+   might return a large offset.  Therefore we must not anymore test
+   for < 0, but test for a real error by making sure the value in %eax
+   is a real error number.  Linus said he will make sure the no
+   syscall returns a value in -1 .. -4095 as a valid result so we can
+   safely test with -4095.
+*/
+static inline SysRes VG_(mk_SysRes_x86_linux) ( Int eax ) {
+   SysRes res;
+   res.isError = eax >= -4095 && eax <= -1;
+   res.val     = res.isError ? -eax : eax;
+   return res;
+}
+
+
 #endif   // __PUB_CORE_LIBCBASE_H
 
 /*--------------------------------------------------------------------*/
diff --git a/coregrind/pub_core_scheduler.h b/coregrind/pub_core_scheduler.h
index db49232..ddc785f 100644
--- a/coregrind/pub_core_scheduler.h
+++ b/coregrind/pub_core_scheduler.h
@@ -138,10 +138,6 @@
       be rare. */
    struct SigQueue *sig_queue;
 
-   /* Syscall the Thread is currently running; -1 if none.  Should only
-      be set while Thread is in VgTs_WaitSys. */
-   Int syscallno;
-
    /* Client stacks.  When a thread slot is freed, we don't deallocate its
       stack; we just leave it lying around for the next use of the
       slot.  If the next use of the slot requires a larger stack,
diff --git a/coregrind/pub_core_signals.h b/coregrind/pub_core_signals.h
index ac64054..444694d 100644
--- a/coregrind/pub_core_signals.h
+++ b/coregrind/pub_core_signals.h
@@ -40,18 +40,19 @@
 
 extern void VG_(sigstartup_actions) ( void );
 
-/* Poll a thread's set of pending signals, and update the Thread's context to deliver one */
+/* Poll a thread's set of pending signals, and update the Thread's
+   context to deliver one (viz, create signal frames if needed) */
 extern void VG_(poll_signals) ( ThreadId );
 
 /* Fake system calls for signal handling. */
-extern Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss,
-                                                   vki_stack_t* oss );
-extern Int VG_(do_sys_sigaction)   ( Int signo, 
-                                     const struct vki_sigaction *new_act, 
-                                     struct vki_sigaction *old_act );
-extern Int VG_(do_sys_sigprocmask) ( ThreadId tid, Int how, 
-                                     vki_sigset_t* set,
-                                     vki_sigset_t* oldset );
+extern SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss,
+                                                      vki_stack_t* oss );
+extern SysRes VG_(do_sys_sigaction)   ( Int signo, 
+                                        const struct vki_sigaction *new_act, 
+                                        struct vki_sigaction *old_act );
+extern SysRes VG_(do_sys_sigprocmask) ( ThreadId tid, Int how, 
+                                        vki_sigset_t* set,
+                                        vki_sigset_t* oldset );
 
 extern void VG_(clear_out_queued_signals) 
                   ( ThreadId tid, /* OUT */ vki_sigset_t* saved_mask );
diff --git a/coregrind/pub_core_syscalls.h b/coregrind/pub_core_syscalls.h
index fed4146..e54dc2c 100644
--- a/coregrind/pub_core_syscalls.h
+++ b/coregrind/pub_core_syscalls.h
@@ -43,23 +43,21 @@
 
 extern void VG_(post_syscall)   ( ThreadId tid );
 
-// Fix up the thread's state because a syscall may have been
-// interrupted with a signal.  Returns True if the syscall completed
-// (either interrupted or finished normally), or False if it was
-// restarted (or the signal didn't actually interrupt a syscall).
-extern void VGP_(interrupted_syscall)(ThreadId tid,
-                                      Word eip, UWord sysnum, UWord sysret,
-                                      Bool restart);
+/* Clear this module's private state for thread 'tid' */
+extern void VG_(clear_syscallInfo) ( Int tid );
+
+// Fix up a thread's state when syscall is interrupted by a signal.
+extern void VG_(fixup_guest_state_after_syscall_interrupted)(
+               ThreadId tid,
+               Addr     ip, 
+               UWord    sysnum,
+               SysRes   sysret,
+               Bool     restart
+            );
 
 // Release resources held by this thread
 extern void VGP_(cleanup_thread) ( ThreadArchState* );
 
-extern Bool VG_(is_kerror) ( Word res );
-
-/* Internal atfork handlers */
-typedef void (*vg_atfork_t)(ThreadId);
-extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child);
-
 /* fd leakage calls. */
 extern void VG_(init_preopened_fds) ( void );
 extern void VG_(show_open_fds) ( void );
diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h
index fbd9770..b779327 100644
--- a/coregrind/pub_core_tooliface.h
+++ b/coregrind/pub_core_tooliface.h
@@ -135,7 +135,7 @@
 
    // VG_(needs).syscall_wrapper
    void (*tool_pre_syscall) (ThreadId, UInt);
-   void (*tool_post_syscall)(ThreadId, UInt, Int);
+   void (*tool_post_syscall)(ThreadId, UInt, SysRes);
 
    // VG_(needs).sanity_checks
    Bool (*tool_cheap_sanity_check)(void);
diff --git a/coregrind/vg_mylibc.c b/coregrind/vg_mylibc.c
index 03effb9..6c0fe19 100644
--- a/coregrind/vg_mylibc.c
+++ b/coregrind/vg_mylibc.c
@@ -36,6 +36,7 @@
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcprint.h"
+#include "pub_core_libcfile.h"
 #include "pub_core_main.h"
 #include "pub_core_options.h"
 #include "pub_core_stacktrace.h"
@@ -159,77 +160,76 @@
 */
 Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
 {
-   Int res = VG_(do_syscall4)(__NR_rt_sigprocmask, 
-                              how, (UWord)set, (UWord)oldset, 
-                              _VKI_NSIG_WORDS * sizeof(UWord));
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask, 
+                                 how, (UWord)set, (UWord)oldset, 
+                                 _VKI_NSIG_WORDS * sizeof(UWord));
+   return res.isError ? -1 : 0;
 }
 
 
 Int VG_(sigaction) ( Int signum, const struct vki_sigaction* act,  
                      struct vki_sigaction* oldact)
 {
-   Int res = VG_(do_syscall4)(__NR_rt_sigaction,
-		              signum, (UWord)act, (UWord)oldact, 
-		              _VKI_NSIG_WORDS * sizeof(UWord));
-   /* VG_(printf)("res = %d\n",res); */
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
+                                 signum, (UWord)act, (UWord)oldact, 
+                                 _VKI_NSIG_WORDS * sizeof(UWord));
+   return res.isError ? -1 : 0;
 }
 
 
 Int VG_(sigaltstack)( const vki_stack_t* ss, vki_stack_t* oss )
 {
-   Int res = VG_(do_syscall2)(__NR_sigaltstack, (UWord)ss, (UWord)oss);
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall2)(__NR_sigaltstack, (UWord)ss, (UWord)oss);
+   return res.isError ? -1 : 0;
 }
 
 Int VG_(sigtimedwait)( const vki_sigset_t *set, vki_siginfo_t *info, 
                        const struct vki_timespec *timeout )
 {
-   Int res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info, 
-                              (UWord)timeout, sizeof(*set));
-
-   return res;
+   SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info, 
+                                 (UWord)timeout, sizeof(*set));
+   return res.isError ? -1 : res.val;
 }
  
 Int VG_(signal)(Int signum, void (*sighandler)(Int))
 {
-   Int res;
+   SysRes res;
+   Int    n;
    struct vki_sigaction sa;
    sa.ksa_handler = sighandler;
    sa.sa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
    sa.sa_restorer = NULL;
-   res = VG_(sigemptyset)( &sa.sa_mask );
-   vg_assert(res == 0);
+   n = VG_(sigemptyset)( &sa.sa_mask );
+   vg_assert(n == 0);
    res = VG_(do_syscall4)(__NR_rt_sigaction, signum, (UWord)&sa, (UWord)NULL,
-			 _VKI_NSIG_WORDS * sizeof(UWord));
-   return VG_(is_kerror)(res) ? -1 : 0;
+                           _VKI_NSIG_WORDS * sizeof(UWord));
+   return res.isError ? -1 : 0;
 }
 
 
 Int VG_(kill)( Int pid, Int signo )
 {
-   Int res = VG_(do_syscall2)(__NR_kill, pid, signo);
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
+   return res.isError ? -1 : 0;
 }
 
 
 Int VG_(tkill)( ThreadId tid, Int signo )
 {
-   Int ret = -VKI_ENOSYS;
+   SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
 
 #if 0
    /* This isn't right because the client may create a process
       structure with multiple thread groups */
-   ret = VG_(do_syscall)(__NR_tgkill, VG_(getpid)(), tid, signo);
+   res = VG_(do_syscall)(__NR_tgkill, VG_(getpid)(), tid, signo);
 #endif
 
-   ret = VG_(do_syscall2)(__NR_tkill, tid, signo);
+   res = VG_(do_syscall2)(__NR_tkill, tid, signo);
 
-   if (ret == -VKI_ENOSYS)
-      ret = VG_(do_syscall2)(__NR_kill, tid, signo);
+   if (res.isError && res.val == VKI_ENOSYS)
+      res = VG_(do_syscall2)(__NR_kill, tid, signo);
 
-   return VG_(is_kerror)(ret) ? -1 : 0;
+   return res.isError ? -1 : 0;
 }
 
 Int VG_(sigpending) ( vki_sigset_t* set )
@@ -241,27 +241,23 @@
 #ifdef __amd64__
    I_die_here;
 #else
-   Int res = VG_(do_syscall1)(__NR_sigpending, (UWord)set);
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall1)(__NR_sigpending, (UWord)set);
+   return res.isError ? -1 : 0;
 #endif
 }
 
 Int VG_(waitpid)(Int pid, Int *status, Int options)
 {
-   Int ret = VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, options, 0);
-
-   return VG_(is_kerror)(ret) ? -1 : ret;
+   SysRes res = VG_(do_syscall4)(__NR_wait4, pid, (UWord)status, options, 0);
+   return res.isError ? -1 : res.val;
 }
 
 Int VG_(gettid)(void)
 {
-   Int ret;
+   SysRes res = VG_(do_syscall0)(__NR_gettid);
 
-   ret = VG_(do_syscall0)(__NR_gettid);
-
-   if (ret == -VKI_ENOSYS) {
-      Char pid[16];
-      
+   if (res.isError && res.val == VKI_ENOSYS) {
+      Char pid[16];      
       /*
        * The gettid system call does not exist. The obvious assumption
        * to make at this point would be that we are running on an older
@@ -275,15 +271,16 @@
        * So instead of calling getpid here we use readlink to see where
        * the /proc/self link is pointing...
        */
-      if ((ret = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
-                                  (UWord)pid, sizeof(pid))) >= 0) 
-      {
-         pid[ret] = '\0';
-         ret = VG_(atoll)(pid);
+
+      res = VG_(do_syscall3)(__NR_readlink, (UWord)"/proc/self",
+                             (UWord)pid, sizeof(pid));
+      if (!res.isError && res.val > 0) {
+         pid[res.val] = '\0';
+         res.val = VG_(atoll)(pid);
       }
    }
 
-   return ret;
+   return res.val;
 }
 
 
@@ -292,11 +289,11 @@
    mmap/munmap, exit, fcntl
    ------------------------------------------------------------------ */
 
-void* VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
-                       UInt fd, OffT offset)
+SysRes VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags,
+                        UInt fd, OffT offset)
 {
-   UWord ret;
-#if defined(VGP_x86_linux)
+   SysRes res;
+#  if defined(VGP_x86_linux)
    { 
       UWord args[6];
       args[0] = (UWord)start;
@@ -305,22 +302,22 @@
       args[3] = flags;
       args[4] = fd;
       args[5] = offset;
-      ret = VG_(do_syscall1)(__NR_mmap, (UWord)args );
+      res = VG_(do_syscall1)(__NR_mmap, (UWord)args );
    }
-#elif defined(VGP_amd64_linux)
-   ret = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, 
+#  elif defined(VGP_amd64_linux)
+   res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length, 
                          prot, flags, fd, offset);
-#else
-#  error Unknown platform
-#endif
-   return VG_(is_kerror)(ret) ? (void*)-1 : (void*)ret;
+#  else
+#    error Unknown platform
+#  endif
+   return res;
 }
 
 /* Returns -1 on failure. */
 void* VG_(mmap)( void* start, SizeT length,
                  UInt prot, UInt flags, UInt sf_flags, UInt fd, OffT offset)
 {
-   Addr  res;
+   SysRes res;
 
    if (!(flags & VKI_MAP_FIXED)) {
       start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
@@ -330,16 +327,18 @@
    if (start == 0)
       return (void *)-1;
 
-   res = (Addr)VG_(mmap_native)(start, length, prot, 
-                                flags & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
-                                fd, offset);
+   res = VG_(mmap_native)(start, length, prot, 
+                          flags & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
+                          fd, offset);
 
    // Check it ended up in the right place.
-   if (res != (Addr)-1) {
+   if (!res.isError) {
       if (flags & VKI_MAP_CLIENT) {
-         vg_assert(VG_(client_base) <= res && res+length <= VG_(client_end));
+         vg_assert(VG_(client_base) <= res.val 
+                   && res.val+length <= VG_(client_end));
       } else {
-         vg_assert(VG_(valgrind_base) <= res && res+length-1 <= VG_(valgrind_last));
+         vg_assert(VG_(valgrind_base) <= res.val 
+                   && res.val+length-1 <= VG_(valgrind_last));
       }
 
       sf_flags |= SF_MMAP;
@@ -349,16 +348,16 @@
       if (!(flags & VKI_MAP_CLIENT))    sf_flags |= SF_VALGRIND;
       if (  flags & VKI_MAP_NOSYMS)     sf_flags |= SF_NOSYMS;
 
-      VG_(map_fd_segment)(res, length, prot, sf_flags, fd, offset, NULL);
+      VG_(map_fd_segment)(res.val, length, prot, sf_flags, fd, offset, NULL);
    }
 
-   return (void*)res;
+   return res.isError ? (void*)-1 : (void*)res.val;
 }
 
 static Int munmap_native(void *start, SizeT length)
 {
-   Int res = VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
+   return res.isError ? -1 : 0;
 }
 
 /* Returns -1 on failure. */
@@ -372,8 +371,8 @@
 
 Int VG_(mprotect_native)( void *start, SizeT length, UInt prot )
 {
-   Int res = VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
-   return VG_(is_kerror)(res) ? -1 : 0;
+   SysRes res = VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
+   return res.isError ? -1 : 0;
 }
 
 Int VG_(mprotect)( void *start, SizeT length, UInt prot )
@@ -398,15 +397,15 @@
 /* Returns -1 on error. */
 Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
 {
-   Int res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
-   return VG_(is_kerror)(res) ? -1 : res;
+   SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
+   return res.isError ? -1 : res.val;
 }
 
 Int VG_(poll)( struct vki_pollfd *ufds, UInt nfds, Int timeout)
 {
-   Int res = VG_(do_syscall3)(__NR_poll, (UWord)ufds, nfds, timeout);
-
-   return res;
+   SysRes res = VG_(do_syscall3)(__NR_poll, (UWord)ufds, nfds, timeout);
+   /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+   return res.val;
 }
 
 
@@ -543,56 +542,49 @@
 /* Support for getrlimit. */
 Int VG_(getrlimit) (Int resource, struct vki_rlimit *rlim)
 {
-   Int res = -VKI_ENOSYS;
+   SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    /* res = getrlimit( resource, rlim ); */
 #  ifdef __NR_ugetrlimit
    res = VG_(do_syscall2)(__NR_ugetrlimit, resource, (UWord)rlim);
 #  endif
-   if (res == -VKI_ENOSYS)
+   if (res.isError && res.val == VKI_ENOSYS)
       res = VG_(do_syscall2)(__NR_getrlimit, resource, (UWord)rlim);
-   if (VG_(is_kerror)(res)) res = -1;
-   return res;
+   return res.isError ? -1 : res.val;
 }
 
 
 /* Support for setrlimit. */
 Int VG_(setrlimit) (Int resource, const struct vki_rlimit *rlim)
 {
-   Int res;
+   SysRes res;
    /* res = setrlimit( resource, rlim ); */
    res = VG_(do_syscall2)(__NR_setrlimit, resource, (UWord)rlim);
-   if (VG_(is_kerror)(res)) res = -1;
-   return res;
+   return res.isError ? -1 : res.val;
 }
 
-
 /* You'd be amazed how many places need to know the current pid. */
 Int VG_(getpid) ( void )
 {
-   Int res;
-   /* res = getpid(); */
-   res = VG_(do_syscall0)(__NR_getpid);
-   return res;
+   /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+   return VG_(do_syscall0)(__NR_getpid) . val;
 }
 
 Int VG_(getpgrp) ( void )
 {
-   Int res;
-   /* res = getpgid(); */
-   res = VG_(do_syscall0)(__NR_getpgrp);
-   return res;
+   /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+   return VG_(do_syscall0)(__NR_getpgrp) . val;
 }
 
 Int VG_(getppid) ( void )
 {
-   Int res;
-   res = VG_(do_syscall0)(__NR_getppid);
-   return res;
+   /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+   return VG_(do_syscall0)(__NR_getppid) . val;
 }
 
 Int VG_(setpgid) ( Int pid, Int pgrp )
 {
-   return VG_(do_syscall2)(__NR_setpgid, pid, pgrp);
+   /* ASSUMES SYSCALL ALWAYS SUCCEEDS */
+   return VG_(do_syscall2)(__NR_setpgid, pid, pgrp) . val;
 }
 
 /* Walk through a colon-separated environment variable, and remove the
@@ -695,12 +687,14 @@
    child! */
 Int VG_(system) ( Char* cmd )
 {
-   Int pid, res;
+   Int    pid;
+   SysRes res;
    if (cmd == NULL)
       return 1;
-   pid = VG_(do_syscall0)(__NR_fork);
-   if (VG_(is_kerror)(pid))
+   res = VG_(do_syscall0)(__NR_fork);
+   if (res.isError)
       return -1;
+   pid = res.val;
    if (pid == 0) {
       /* child */
       static Char** envp = NULL;
@@ -724,12 +718,8 @@
       VG_(exit)(1);
    } else {
       /* parent */
-      res = VG_(waitpid)(pid, NULL, 0);
-      if (VG_(is_kerror)(res)) {
-         return -1;
-      } else {
-	 return 0;
-      }
+      Int zzz = VG_(waitpid)(pid, NULL, 0);
+      return zzz == -1 ? -1 : 0;
    }
 }
 
@@ -742,8 +732,8 @@
 {
    static ULong base = 0;
    struct vki_timeval tv_now;
-   ULong now;
-   Int res;
+   ULong  now;
+   SysRes res;
 
    res = VG_(do_syscall2)(__NR_gettimeofday, (UWord)&tv_now, (UWord)NULL);
    
@@ -758,7 +748,7 @@
 
 void VG_(nanosleep)(struct vki_timespec *ts)
 {
-   VG_(do_syscall2)(__NR_nanosleep, (UWord)ts, (UWord)NULL);
+   (void)VG_(do_syscall2)(__NR_nanosleep, (UWord)ts, (UWord)NULL);
 }
 
 /* ---------------------------------------------------------------------
@@ -795,6 +785,75 @@
    VG_(exit)(1);
 }
 
+/* ---------------------------------------------------------------------
+   Misc stuff looking for a proper home
+   ------------------------------------------------------------------ */
+
+/* ---------------------------------------------------------------------
+   A simple atfork() facility for Valgrind's internal use
+   ------------------------------------------------------------------ */
+
+struct atfork {
+   vg_atfork_t	pre;
+   vg_atfork_t	parent;
+   vg_atfork_t	child;
+};
+
+#define VG_MAX_ATFORK	10
+
+static struct atfork atforks[VG_MAX_ATFORK];
+static Int n_atfork;
+
+void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child)
+{
+   Int i;
+
+   for(i = 0; i < n_atfork; i++) {
+      if (atforks[i].pre == pre &&
+          atforks[i].parent == parent &&
+          atforks[i].child == child)
+         return;
+   }
+
+   if (n_atfork >= VG_MAX_ATFORK)
+      VG_(core_panic)("Too many VG_(atfork) handlers requested: "
+                      "raise VG_MAX_ATFORK");
+
+   atforks[n_atfork].pre    = pre;
+   atforks[n_atfork].parent = parent;
+   atforks[n_atfork].child  = child;
+
+   n_atfork++;
+}
+
+void VG_(do_atfork_pre)(ThreadId tid)
+{
+   Int i;
+
+   for(i = 0; i < n_atfork; i++)
+      if (atforks[i].pre != NULL)
+	 (*atforks[i].pre)(tid);
+}
+
+void VG_(do_atfork_parent)(ThreadId tid)
+{
+   Int i;
+
+   for(i = 0; i < n_atfork; i++)
+      if (atforks[i].parent != NULL)
+	 (*atforks[i].parent)(tid);
+}
+
+void VG_(do_atfork_child)(ThreadId tid)
+{
+   Int i;
+
+   for(i = 0; i < n_atfork; i++)
+      if (atforks[i].child != NULL)
+	 (*atforks[i].child)(tid);
+}
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
diff --git a/include/basic_types.h b/include/basic_types.h
index 10c0f35..6e02b3d 100644
--- a/include/basic_types.h
+++ b/include/basic_types.h
@@ -71,6 +71,17 @@
    UInt
    ThreadId;
 
+/* An abstraction of syscall return values.
+   When .isError == False, val holds the return value.
+   When .isError == True,  val holds the error code.
+*/
+typedef
+   struct { 
+      UWord val;
+      Bool  isError;
+   }
+   SysRes;
+
 /* ---------------------------------------------------------------------
    Where to send bug reports to.
    ------------------------------------------------------------------ */
diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h
index 2c45906..5514080 100644
--- a/include/pub_tool_tooliface.h
+++ b/include/pub_tool_tooliface.h
@@ -235,7 +235,7 @@
 // corresponding post_ function had better free() it!
 extern void VG_(needs_syscall_wrapper) (
    void (* pre_syscall)(ThreadId tid, UInt syscallno),
-   void (*post_syscall)(ThreadId tid, UInt syscallno, Int res)
+   void (*post_syscall)(ThreadId tid, UInt syscallno, SysRes res)
 );
 
 /* Are tool-state sanity checks performed? */