Add support for ARMv8 AArch64 (the 64 bit ARM instruction set).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13770 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 4f6d3d0..f5d51af 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -116,8 +116,12 @@
 }
 
 SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode )
-{  
-#  if defined(VGO_linux)
+{
+#  if defined(VGP_arm64_linux)
+   /* ARM64 wants to use __NR_openat rather than __NR_open. */
+   SysRes res = VG_(do_syscall4)(__NR_openat,
+                                 VKI_AT_FDCWD, (UWord)pathname, flags, mode);
+#  elif defined(VGO_linux)
    SysRes res = VG_(do_syscall3)(__NR_open,
                                  (UWord)pathname, flags, mode);
 #  elif defined(VGO_darwin)
@@ -204,6 +208,9 @@
    } else {
       return -1;
    }
+#  elif defined(VGP_arm64_linux)
+   SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0);
+   return sr_isError(res) ? -1 : 0;
 #  elif defined(VGO_linux)
    SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
    return sr_isError(res) ? -1 : 0;
@@ -289,8 +296,14 @@
      }
    }
 #  endif /* defined(__NR_stat64) */
+   /* This is the fallback ("vanilla version"). */
    { struct vki_stat buf;
+#    if defined(VGP_arm64_linux)
+     res = VG_(do_syscall3)(__NR3264_fstatat, VKI_AT_FDCWD,
+                                              (UWord)file_name, (UWord)&buf);
+#    else
      res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
+#    endif
      if (!sr_isError(res))
         TRANSLATE_TO_vg_stat(vgbuf, &buf);
      return res;
@@ -385,7 +398,12 @@
 
 Int VG_(unlink) ( const HChar* file_name )
 {
+#  if defined(VGP_arm64_linux)
+   SysRes res = VG_(do_syscall2)(__NR_unlinkat, VKI_AT_FDCWD,
+                                                (UWord)file_name);
+#  else
    SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
+#  endif
    return sr_isError(res) ? (-1) : 0;
 }
 
@@ -474,7 +492,12 @@
 {
    SysRes res;
    /* res = readlink( path, buf, bufsiz ); */
+#  if defined(VGP_arm64_linux)
+   res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
+                                           (UWord)path, (UWord)buf, bufsiz);
+#  else
    res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
+#  endif
    return sr_isError(res) ? -1 : sr_Res(res);
 }
 
@@ -509,7 +532,11 @@
    UWord w = (irusr ? VKI_R_OK : 0)
              | (iwusr ? VKI_W_OK : 0)
              | (ixusr ? VKI_X_OK : 0);
+#  if defined(VGP_arm64_linux)
+   SysRes res = VG_(do_syscall3)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path, w);
+#  else
    SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
+#  endif
    return sr_isError(res) ? 1 : 0;   
 
 #  if defined(VGO_linux)
@@ -624,7 +651,8 @@
    return res;
 #  elif defined(VGP_amd64_linux) \
       || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
-      || defined(VGP_mips64_linux) 
+      || defined(VGP_mips64_linux) \
+      || defined(VGP_arm64_linux)
    res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
    return res;
 #  elif defined(VGP_amd64_darwin)
@@ -877,7 +905,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
+        || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
    return sr_isError(res) ? -1 : sr_Res(res);
@@ -916,7 +945,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
+        || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
    return sr_isError(res) ? -1 : sr_Res(res);
@@ -955,7 +985,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
+        || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg, 
                                        count, VKI_MSG_NOSIGNAL, 0,0);
@@ -985,7 +1016,7 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips64_linux)
+        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall3)( __NR_getsockname,
                            (UWord)sd, (UWord)name, (UWord)namelen );
@@ -1016,7 +1047,7 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips64_linux)
+        || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall3)( __NR_getpeername,
                            (UWord)sd, (UWord)name, (UWord)namelen );
@@ -1049,7 +1080,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
+        || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall5)( __NR_getsockopt,
                            (UWord)sd, (UWord)level, (UWord)optname, 
@@ -1085,7 +1117,8 @@
    return sr_isError(res) ? -1 : sr_Res(res);
 
 #  elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
-        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+        || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
+        || defined(VGP_arm64_linux)
    SysRes res;
    res = VG_(do_syscall5)( __NR_setsockopt,
                            (UWord)sd, (UWord)level, (UWord)optname,