UPDATE : valgrind version update and add files for SDK package
[sdk/tools/upstream/valgrind.git] / coregrind / m_syswrap / syswrap-s390x-linux.c
index 4880226..8bbdf3d 100644 (file)
@@ -7,7 +7,7 @@
    This file is part of Valgrind, a dynamic binary instrumentation
    framework.
 
-   Copyright IBM Corp. 2010-2011
+   Copyright IBM Corp. 2010-2013
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -123,7 +123,7 @@ asm(
             long   flags         in r3
             int*   parent_tid    in r4
             int*   child_tid     in r5
-            int*   child_tid     in r6
+            int*   tls address   in r6
             Word   (*fn)(void *) 160(r15)
             void   *arg          168(r15)
 
@@ -143,14 +143,15 @@ asm(
 extern
 ULong do_syscall_clone_s390x_linux ( void  *stack,
                                      ULong flags,
-                                     Int   *child_tid,
                                      Int   *parent_tid,
+                                     Int   *child_tid,
                                      Addr  tlsaddr,
                                      Word (*fn)(void *),
                                      void  *arg);
 asm(
    "   .text\n"
    "   .align  4\n"
+   ".globl do_syscall_clone_s390x_linux\n"
    "do_syscall_clone_s390x_linux:\n"
    "   lg    %r1, 160(%r15)\n"   // save fn from parent stack into r1
    "   lg    %r0, 168(%r15)\n"   // save arg from parent stack into r0
@@ -287,6 +288,7 @@ static SysRes do_clone ( ThreadId ptid,
       know that this thread has come into existence.  If the clone
       fails, we'll send out a ll_exit notification for it at the out:
       label below, to clean up. */
+   vg_assert(VG_(owns_BigLock_LL)(ptid));
    VG_TRACK ( pre_thread_ll_create, ptid, ctid );
 
    if (flags & VKI_CLONE_SETTLS) {
@@ -302,7 +304,7 @@ static SysRes do_clone ( ThreadId ptid,
 
    /* Create the new thread */
    r2 = do_syscall_clone_s390x_linux(
-            stack, flags, child_tidptr, parent_tidptr, tlsaddr,
+            stack, flags, parent_tidptr, child_tidptr, tlsaddr,
             ML_(start_thread_NORETURN), &VG_(threads)[ctid]);
 
    res = VG_(mk_SysRes_s390x_linux)( r2 );
@@ -337,18 +339,19 @@ static SysRes do_clone ( ThreadId ptid,
    magic. */
 
 DECL_TEMPLATE(s390x_linux, sys_ptrace);
-DECL_TEMPLATE(s390x_linux, sys_socketcall);
 DECL_TEMPLATE(s390x_linux, sys_mmap);
-DECL_TEMPLATE(s390x_linux, sys_ipc);
 DECL_TEMPLATE(s390x_linux, sys_clone);
 DECL_TEMPLATE(s390x_linux, sys_sigreturn);
 DECL_TEMPLATE(s390x_linux, sys_rt_sigreturn);
 DECL_TEMPLATE(s390x_linux, sys_fadvise64);
 
-// PEEK TEXT,DATA and USER are common to all architectures
-// PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
-// containing the real addr, data, and len field pointed to by ARG3
-// instead of ARG4
+/* PEEK TEXT,DATA and USER are common to all architectures.
+   PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
+   containing the real addr, data, and len field pointed to by ARG3
+   instead of ARG4.
+   GETREGSET and SETREGSET use a struct iovec (pointed to by ARG4) for
+   the address and size of the user buffer. */
+
 PRE(sys_ptrace)
 {
    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
@@ -404,6 +407,12 @@ PRE(sys_ptrace)
                        pa->vki_process_addr, pa->vki_len);
          break;
       }
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+      break;
+   case VKI_PTRACE_SETREGSET:
+      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+      break;
    default:
       break;
    }
@@ -432,328 +441,14 @@ POST(sys_ptrace)
 
         pa = (vki_ptrace_area *) ARG3;
          POST_MEM_WRITE(pa->vki_process_addr, pa->vki_len);
+        break;
       }
-   default:
-      break;
-   }
-}
-
-
-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 ( %ld, %#lx )",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) );
-      if (!ML_(valid_client_addr)(ARG2, 4*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-      }
-      ML_(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) );
-      if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-      }
-      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) );
-      if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-      }
-      ML_(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) );
-      if (!ML_(valid_client_addr)(ARG2, 2*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-      }
+   case VKI_PTRACE_GETREGSET:
+      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
       break;
-
-   case VKI_SYS_ACCEPT: {
-     /* int accept(int s, struct sockaddr *addr, int *addrlen); */
-      PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
-      if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-      }
-      ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 6*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 4*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 6*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 4*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 5*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 5*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(linux_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) );
-     if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(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) );
-     if (!ML_(valid_client_addr)(ARG2, 2*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     break;
-
-   case VKI_SYS_SENDMSG: {
-     /* int sendmsg(int s, const struct msghdr *msg, int flags); */
-     PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
-     if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
-     break;
-   }
-
-   case VKI_SYS_RECVMSG: {
-     /* int recvmsg(int s, struct msghdr *msg, int flags); */
-     PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
-     if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
-         SET_STATUS_Failure( VKI_EFAULT );
-         break;
-     }
-     ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
-     break;
-   }
-
    default:
-     VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
-     SET_STATUS_Failure( VKI_EINVAL );
-     break;
+      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 = ML_(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 = ML_(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 = ML_(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:
-    ML_(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:
-    ML_(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:
-    ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
-                                     ARG2_0, ARG2_1,
-                                     ARG2_2, ARG2_3, ARG2_4 );
-    break;
-
-  case VKI_SYS_GETSOCKNAME:
-    ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
-                                      ARG2_0, ARG2_1, ARG2_2 );
-    break;
-
-  case VKI_SYS_GETPEERNAME:
-    ML_(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:
-    ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
-    break;
-
-  default:
-    VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",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_mmap)
@@ -779,160 +474,6 @@ PRE(sys_mmap)
    SET_STATUS_from_SysRes(r);
 }
 
-static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
-{
-   Addr* a_p = (Addr*)a;
-   PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
-   return *a_p;
-}
-
-PRE(sys_ipc)
-{
-  PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )",
-        ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
-  // XXX: this is simplistic -- some args are not used in all circumstances.
-  PRE_REG_READ6(int, "ipc",
-               vki_uint, call, int, first, int, second, int, third,
-               void *, ptr, long, fifth)
-
-    switch (ARG1 /* call */) {
-    case VKI_SEMOP:
-      ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
-      *flags |= SfMayBlock;
-      break;
-    case VKI_SEMGET:
-      break;
-    case VKI_SEMCTL:
-      {
-       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
-       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
-       break;
-      }
-    case VKI_SEMTIMEDOP:
-      ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
-      *flags |= SfMayBlock;
-      break;
-    case VKI_MSGSND:
-      ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
-      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
-       *flags |= SfMayBlock;
-      break;
-    case VKI_MSGRCV:
-      {
-       Addr msgp;
-       Word msgtyp;
-
-       msgp = deref_Addr( tid,
-                          (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
-                          "msgrcv(msgp)" );
-       msgtyp = deref_Addr( tid,
-                            (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
-                            "msgrcv(msgp)" );
-
-       ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
-
-       if ((ARG4 & VKI_IPC_NOWAIT) == 0)
-         *flags |= SfMayBlock;
-       break;
-      }
-    case VKI_MSGGET:
-      break;
-    case VKI_MSGCTL:
-      ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
-      break;
-    case VKI_SHMAT:
-      {
-       UWord w;
-       PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
-       w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
-       if (w == 0)
-         SET_STATUS_Failure( VKI_EINVAL );
-       else
-         ARG5 = w;
-       break;
-      }
-    case VKI_SHMDT:
-      if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
-       SET_STATUS_Failure( VKI_EINVAL );
-      break;
-    case VKI_SHMGET:
-      break;
-    case VKI_SHMCTL: /* IPCOP_shmctl */
-      ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
-      break;
-    default:
-      VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld", ARG1 );
-      VG_(core_panic)("... bye!\n");
-      break; /*NOTREACHED*/
-    }
-}
-
-POST(sys_ipc)
-{
-  vg_assert(SUCCESS);
-  switch (ARG1 /* call */) {
-  case VKI_SEMOP:
-  case VKI_SEMGET:
-    break;
-  case VKI_SEMCTL:
-    {
-      UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
-      ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
-      break;
-    }
-  case VKI_SEMTIMEDOP:
-  case VKI_MSGSND:
-    break;
-  case VKI_MSGRCV:
-    {
-      Addr msgp;
-      Word msgtyp;
-
-      msgp = deref_Addr( tid,
-                         (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
-                         "msgrcv(msgp)" );
-      msgtyp = deref_Addr( tid,
-                           (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
-                           "msgrcv(msgp)" );
-
-      ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
-      break;
-    }
-  case VKI_MSGGET:
-    break;
-  case VKI_MSGCTL:
-    ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
-    break;
-  case VKI_SHMAT:
-    {
-      Addr addr;
-
-      /* force readability. before the syscall it is
-       * indeed uninitialized, as can be seen in
-       * glibc/sysdeps/unix/sysv/linux/shmat.c */
-      POST_MEM_WRITE( ARG4, sizeof( Addr ) );
-
-      addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
-      ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
-      break;
-    }
-  case VKI_SHMDT:
-    ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
-    break;
-  case VKI_SHMGET:
-    break;
-  case VKI_SHMCTL:
-    ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
-    break;
-  default:
-    VG_(message)(Vg_DebugMsg,
-                "FATAL: unhandled syscall(ipc) %ld",
-                ARG1 );
-    VG_(core_panic)("... bye!\n");
-    break; /*NOTREACHED*/
-  }
-}
-
 PRE(sys_clone)
 {
    UInt cloneflags;
@@ -963,6 +504,13 @@ PRE(sys_clone)
       }
    }
 
+   /* The kernel simply copies reg6 (ARG5) into AR0 and AR1, no checks */
+   if (ARG2 & VKI_CLONE_SETTLS) {
+      if (VG_(tdict).track_pre_reg_read) {
+         PRA5("clone", Addr, tlsinfo);
+      }
+   }
+
    cloneflags = ARG2;
 
    if (!ML_(client_signal_OK)(ARG2 & VKI_CSIGNAL)) {
@@ -1227,7 +775,7 @@ static SyscallTableEntry syscall_table[] = {
 
    GENXY(__NR_fstatfs,  sys_fstatfs),                                 // 100
    GENX_(101, sys_ni_syscall), /* unimplemented (by the kernel) */    // 101
-   PLAXY(__NR_socketcall, sys_socketcall),                            // 102
+   LINXY(__NR_socketcall, sys_socketcall),                            // 102
    LINXY(__NR_syslog,  sys_syslog),                                   // 103
    GENXY(__NR_setitimer,  sys_setitimer),                             // 104
 
@@ -1245,7 +793,7 @@ static SyscallTableEntry syscall_table[] = {
 
 // ?????(__NR_swapoff, ),                                             // 115
    LINXY(__NR_sysinfo,  sys_sysinfo),                                 // 116
-   PLAXY(__NR_ipc, sys_ipc),                                          // 117
+   LINXY(__NR_ipc, sys_ipc),                                          // 117
    GENX_(__NR_fsync,  sys_fsync),                                     // 118
    PLAX_(__NR_sigreturn, sys_sigreturn),                              // 119
 
@@ -1503,6 +1051,16 @@ static SyscallTableEntry syscall_table[] = {
 
 // ?????(__NR_rt_tgsigqueueinfo, ),
    LINXY(__NR_perf_event_open, sys_perf_event_open),                  // 331
+// ?????(__NR_fanotify_init, ),                                       // 332
+// ?????(__NR_fanotify_mark, ),                                       // 333
+   LINXY(__NR_prlimit64, sys_prlimit64),                              // 334
+// ?????(__NR_name_to_handle_at, ),                                   // 335
+// ?????(__NR_open_by_handle_at, ),                                   // 336
+// ?????(__NR_clock_adjtime, ),                                       // 337
+// ?????(__NR_syncfs, ),                                              // 338
+// ?????(__NR_setns, ),                                               // 339
+   LINXY(__NR_process_vm_readv, sys_process_vm_readv),                // 340
+   LINX_(__NR_process_vm_writev, sys_process_vm_writev),              // 341
 };
 
 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )